# Account security
Source: https://docs.famulor.io/account-security
Personal details, appearance, sign-in security, and how to delete your account
Open **Settings → Preferences** to manage your own account — the personal details, appearance, and security settings tied to you, separate from any one workspace's settings.
## Personal details
Update your profile picture, first and last name, phone number, and job title. The picture accepts PNG or JPEG, at least 256×256px, and is optimized automatically on upload.
Your email address changes separately: enter the new address, then confirm it from a link sent to that address before the change takes effect.
## Password
Set a new password for your account at any time — you don't need to enter your current one first, since changing it requires an active signed-in session. The new password must be at least 8 characters.
## Appearance and language
Choose **Light**, **Dark**, or **System** to control how Famulor looks; System follows your device setting.
Your language is a personal choice too: leave it on **Automatic** — which follows the workspace default, then the platform default and your location — or pick a language that applies to you from then on, whatever the workspace uses.
The same page also shows **Timezone** and **Date Format**. Those two are workspace-wide rather than personal — owners and admins can change them here or under [Workspace profile](/settings/workspaces#workspace-profile), and everyone else sees them read-only.
## Browser notifications
Where your browser supports it, turn on **Browser notifications** to get privacy-safe alerts on this browser or installed web app — new History activity, and incoming or missed [Famulor Loop](/telephony/famulor-loop) calls, depending on what your workspace has available. Each toggle applies only to the device and browser where you enabled it.
## Two-factor authentication
Two-factor authentication adds a second step after the password. You can enable either or both methods:
* **Authenticator app:** scan the QR code with any TOTP-compatible app and enter its current 6-digit code.
* **Email codes:** confirm the first 6-digit code sent to your account email. Future sign-ins send a new code that expires after 10 minutes.
Turning a method on or off always requires a successful code confirmation. If both methods are enabled, the sign-in screen lets you switch between them.
Email-code messages use the email delivery settings of the brand where you sign in.
For security, MFA can only be changed while you are signed in interactively. API keys and MCP connections cannot change the account's sign-in policy.
## Where you are signed in
The same Preferences page lists devices with active sessions. The list shows the browser, operating system, last activity time, and IP address when available.
Choose **Sign out** on a device you do not recognise. This immediately revokes access for that session.
For privacy and security, access and refresh tokens are never shown in the device list.
## Delete your account
Deleting your account permanently removes it and **every workspace you own** — not just the one you're currently in. Workspaces you've only joined, without owning, are unaffected.
Confirm you understand the consequences, then delete. Removal typically completes within 10 days; contact support under Help within that window if you want to stop it.
# Credit balances & transfers
Source: https://docs.famulor.io/admin/balances-and-transfers
Track prepaid credits and fund customer workspaces
Calling is prepaid. Every workspace has a credit balance, and completed calls reduce that balance according to the workspace's pricing.
## How balances change
A balance can change when:
* included plan credits are added,
* the workspace buys a top-up,
* calls use credits, or
* a white-label reseller transfers credits to or from one of its customer workspaces.
Every change appears in the balance history with its date, amount, reason, and any note supplied with a transfer.
## Transfer credits
White-label workspace owners and admins can fund their customer workspaces from their own available balance. They can also reclaim unused credits, provided the customer workspace has enough remaining balance.
Transfers are immediate and never allow either workspace to fall below zero.
## Buy additional credits
Workspace owners can purchase top-up packages from **Billing**. Once payment is confirmed, the new credits appear in the active workspace.
## Where to see usage
* **Customers** shows the balance for each customer workspace and provides the transfer action.
* **Usage** shows your active workspace's consumption by day and by call.
Balances are credits, not cash. Plan pricing and included usage are described in [Plans & limits](/admin/plans-and-limits) and [Minutes & billing](/billing/minutes).
# Reseller dashboard
Source: https://docs.famulor.io/admin/dashboard
Read the KPI tiles, usage charts, plan margins, and current contribution snapshot on your white-label admin landing page
**Tenant Admin → Dashboard** is the first page you see in your white-label admin console — a live summary of your resale business across every customer workspace. Pick the last 7, 30, or 90 days, or a custom range. Activity figures and the charts follow that selection; running totals such as total users, active subscriptions, and estimated MRR always show the current state.
A short setup checklist appears above the KPIs until you finish initial setup — branding, connecting your domain, completing Stripe onboarding, creating a plan, and configuring SMTP — then it disappears.
## KPI tiles
| Tile | What it counts |
| ------------------------ | ------------------------------------------------------------------------------------------------------------- |
| Total users | Customer workspaces on your domain in total, and how many were created in the selected period |
| Active subscriptions | Subscriptions currently active or in trial, and the share of your customers that represents |
| New subscriptions | Subscriptions started during the selected period |
| Avg revenue / subscriber | Estimated MRR divided by active subscriptions |
| Minutes spent | Call minutes used by your customers, with the change from the prior period |
| Credits spent | Credits spent on calls, email, knowledge-base imports, and add-on fees, with the change from the prior period |
| Estimated MRR | Monthly recurring revenue implied by currently active subscriptions |
| Annual run rate | Estimated MRR × 12 |
| Assistants | Total assistants across your customers, and how many are new this period |
| Voice calls | Voice conversations — phone, WhatsApp voice, and web calls — with the change from the prior period |
| WhatsApp messages | WhatsApp messages sent and received |
| SMS sent | SMS messages in the period, inbound and outbound, with the change from the prior period |
| Web chats | Web-widget text chat conversations, with the change from the prior period |
| API chats | Conversations started through the REST API or MCP |
| Emails | Emails sent and received, with the change from the prior period |
| Campaigns | All campaigns across your customer workspaces, not only those created in the period |
**Estimated MRR** is the monthly recurring revenue implied by your customers' currently active subscriptions, trials included — a projection, not a guarantee of what you'll actually collect, since it doesn't account for failed payments, cancellations, or proration. **Annual run rate** is that figure × 12.
WhatsApp messages and API chats currently show as **Not available yet**.
## Calls and minutes
A daily chart plots calls — web widget conversations included — against total call minutes across every customer workspace, for the selected period. Use it to spot a usage trend early.
## Subscriptions by plan and engagement
A donut chart breaks active subscriptions down by plan. Beside it, engagement rings show what share of your customers hold an active plan and what share actually used the service in the period, plus an overall figure that averages the two.
## Leaderboards and recent activity
Five tables sit below the charts: customers running low on credits, top-spending customers, usage per customer, the most recently created assistants, and your newest customers. Use them to spot who needs a [top-up reminder](/admin/balances-and-transfers) or a follow-up.
## Subscription margin per plan
For each of your plans, this table compares the monthly price against what the plan's included minutes cost you at your platform minute rate, and shows the resulting margin. A plan that costs you more than it brings in is flagged. The same cost and margin figures appear on each plan's own card on the [Plans & limits](/admin/plans-and-limits) page.
## Current subscription contribution
This table is a current snapshot. It estimates current plan MRR from active subscriptions and trials, then subtracts platform call costs accrued month to date. It is **not collected historical revenue**. Trials are included; taxes, refunds, payment fees, non-call costs, and recurring add-ons are excluded.
See also [White-label workspaces](/admin/tenants-and-whitelabel) for customer and domain management, and [Plans & limits](/admin/plans-and-limits) for the plans these figures are measured against.
# Plans & limits
Source: https://docs.famulor.io/admin/plans-and-limits
Create clear white-label customer plans with pricing, included usage, limits, and add-ons
White-label resellers can create plans for their own customer workspaces. Each plan combines pricing, included minutes, usage rules, workspace limits, and product capabilities.
## Plan contents
### Pricing
Choose a monthly or yearly price, the included minutes, and the price for additional usage. The plan card previews what the customer sees before checkout.
### Workspace limits
Common limits include:
| Limit | What it controls |
| ------------------------------------------ | --------------------------------------------------- |
| Assistants | Number of assistants in the workspace |
| Campaigns | Number of saved campaigns |
| Phone numbers | Connected purchased and BYO numbers |
| Team members | People who can join the workspace |
| [Data retention](/settings/data-retention) | Default retention period available to the workspace |
Use **Unlimited** only where the plan editor offers it. A value of zero means the capability is not included.
Add-on-backed capacity cannot be included free in a reseller plan, free-account default, or customer override. This includes extra Concurrent Lines, cloned-voice slots, knowledge bases, tools, CRM sync capacity and contacts, automation runs, and extra workspaces. Every workspace still has its one-line baseline; all additional add-on capacity must be purchased.
### Included capabilities
Plans can include capabilities such as Flow Builder, the web widget, AI Avatar, Connect AI / MCP, additional languages, calendar integrations, custom dashboards, live monitoring, simulations, data retention, website imports, and automatic knowledge sync.
Customers see the included capabilities and limits on the plan card. Actions outside the plan remain unavailable throughout the product and API.
## Add-ons
Optional add-ons are selected from the plan card and billed with the same interval when supported. Platform add-ons are not offered to your customers until you explicitly enable **Offer to my users**. Add-on-backed features such as Fallbacks & Guardrails, Clone your own voice, and Revenue Autopilot, together with their related capacity, are sold here rather than included through **Plans** or **Default plan limits**.
**API Access** follows the same add-on-only rule: it cannot be bundled into a reseller plan, free-account defaults, or a customer override. Offer it explicitly as a recurring add-on. **Connect AI / MCP** remains a separate capability that may still be included in a plan.
When you enable an add-on for resale, set the customer-facing price shown at checkout. Recurring add-on prices are configured separately from [usage pricing](#usage-pricing).
Some usage-based capabilities, such as website imports and automatic sync, are charged in credits according to your usage pricing rather than as recurring add-ons.
## Usage pricing
Beyond the recurring plan price, usage-based actions — call minutes, email, web chat, messaging channels, knowledge-base crawl and sync, re-transcription, SMS, simulator messages, history re-evaluation, and automation runs — are billed in credits at rates you set on the **Usage pricing** page.
Set the customer-facing rates for credit-metered actions on the **Usage pricing** page. These rates are separate from subscription and recurring add-on prices.
Your customers see the resulting rates on their own Usage page.
## Registration and prepaid accounts
Under **Default plan limits**, self-service registration controls whether new customers can create an account on your verified white-label domain. Prepaid access is a separate switch: it controls whether a customer without a paid plan can use prepaid credits. When prepaid access is off, registration can remain open, but the customer must select a paid plan before using the platform. Configure the prepaid limits and pay-as-you-go minute price on the same page.
## Publishing and changing plans
Review the customer-facing name, description, limits, prices, and checkout before publishing a plan. Paid plan changes take effect through the billing flow. Included minutes are credited according to the customer's billing cycle.
The plan editor prevents incomplete or invalid pricing combinations. Existing customers keep access according to their active subscription and any changes shown in the billing flow.
See [How minutes are billed](/billing/minutes) and [Billing setup](/admin/stripe) for the customer billing experience.
# Payments with Stripe
Source: https://docs.famulor.io/admin/stripe
Manage workspace billing and charge white-label customers
Famulor uses Stripe for secure subscription payments, credit top-ups, and phone-number charges. Workspace owners manage payment methods, invoices, and cancellations through the Stripe customer portal opened from **Billing**.
## Billing your white-label customers
White-label resellers can connect their own Stripe account and sell plans under their own brand.
Open **Billing platform** in the white-label admin area and complete Stripe's guided onboarding. The page shows when the account is ready to accept payments and receive payouts.
Define the prices, included credits, limits, and optional add-ons you want to offer. See [Plans & limits](/admin/plans-and-limits).
Customers choose a plan through checkout on your branded domain. Payments are collected through your connected account and your applicable platform fees are shown in the billing area.
Use Stripe for payout and payment details. Use [Famulor's billing overview](/admin/dashboard) to compare plan revenue with your service costs.
## What customers can manage
Customers can open their billing portal to:
* update payment methods,
* download invoices,
* change or cancel a subscription, and
* buy additional credits when available.
Availability and payout timing depend on the status and country of your connected Stripe account.
# White-label workspaces
Source: https://docs.famulor.io/admin/tenants-and-whitelabel
Brand your reseller workspace, manage customer workspaces, and support your users
White-label access lets an existing workspace operate as a branded reseller environment. Customers use your domain and branding while their assistants, calls, campaigns, plan, credits, and team remain isolated in separate customer workspaces.
White-label access comes either with a plan tier that includes it or as a standalone add-on bought from **Settings → Plan**. Unlike Fallbacks & Guardrails, Clone your own voice, and Revenue Autopilot, it can never be resold onward to your own customers.
## What you can customise
* **Domain** — app, login, public API (`/api/v1`), and [MCP](/mcp/overview) use your verified domain.
* **Branding** — app name, logos, favicon, colours, and authentication screens.
* **Support details** — the contact information shown to your customers.
* **[Plans and pricing](/admin/plans-and-limits)** — customer-facing plans, included minutes, limits, and add-ons.
* **[Billing](/admin/stripe)** — customer checkout, subscriptions, top-ups, and invoices through your connected billing account.
* **Currency** — the display currency your customers see; stored prices remain in EUR and convert at a platform-managed rate.
* **Custom SMTP server** — send transactional email to your customers through your own mail provider instead of the platform default.
* **Mail template** — the welcome email sent right after a customer creates an account; leave fields blank to use the default text.
* **Email notifications** — which transactional emails go out to your customers.
* **Signup webhook** — an HTTP callback fired when someone signs up on your domain.
* **Bot protection** — an optional Cloudflare Turnstile challenge on your signup form, available once your custom domain is verified.
* **Retention limits** — the min/max range your customers can choose for their own data retention, separate from the default retention period you set on each plan.
White-label administration appears only when your workspace has White-label access.
## Customer workspaces
When a person registers on your white-label domain, Famulor creates a separate customer workspace owned by that person. The customer does not become a member of your reseller workspace.
This separation keeps customer resources, billing, credits, and team access independent. Manage customers from the **Tenant Admin** area or use the [White Label API](/admin/whitelabel-api) for your own onboarding and support workflows.
Open a single customer under **Users** to reach two override tools, both scoped to that one customer only:
* **Custom User Appearance** hides specific navigation pages or product features from that customer, independent of your global white-label branding and navigation.
* **Custom User Limits** overrides individual plan-limit values — such as the number of assistants, campaigns, or team members — for that one workspace. An override here takes priority over whatever the customer's subscribed plan specifies.
## Cross-customer history and live monitoring
Your admin console has its own **History** and **Live monitoring** views that aggregate every customer workspace into one place, so support and quality checks do not mean opening each workspace in turn. They are separate from the single-workspace [History](/monitoring/history) and [Live monitoring](/monitoring/live-monitoring) your customers use inside the product.
Admin History lists calls, email, and messaging conversations from every customer workspace in one grid, with a **Workspace** column identifying which customer each conversation belongs to, and opens the same detail views as the customer-facing History.
Admin Live monitoring shows the active calls across all your customer workspaces. On any of them you can listen in, whisper to the assistant, take over the conversation, or hang up — the same controls as a single workspace's own Live monitoring — alongside response-latency percentiles from the last 24 hours. This view is gated by your own reseller plan's **Live monitoring** capability, not by any individual customer's plan.
## Connect a custom domain
Open **Tenant Admin → Settings** and add the full hostname you want to use.
1. Publish the ownership TXT record shown in the setup.
2. Publish the recommended A or CNAME record for routing.
3. Wait for DNS propagation, then choose **Check DNS**.
The domain becomes active only after ownership, routing, and certificate checks succeed. Removing the domain disables sign-in and branding on that hostname.
The same workflow is available through `GET`, `POST`, and `DELETE /api/v1/custom-domain`, `POST /api/v1/custom-domain/verify`, and the matching MCP tools.
## Registration and prepaid accounts
Under **Tenant Admin → Default plan limits**, **Allow self-service registration** controls only whether new customers can create an account from your verified custom-domain login page. Existing customers can still sign in when it is off, and customers created by an authorised reseller operator through the dashboard, REST API, or MCP remain available.
**Allow prepaid accounts** is independent. It controls whether customers without a paid plan can use prepaid credits. When it is off, registration may still be open, but new customers must choose a paid plan before using the platform. Prepaid limits and the pay-as-you-go minute price apply until a customer selects a paid plan.
You can also set **Welcome credits for new customers** on the same page. The recommended starting value is 800 credits. Each new prepaid customer receives the configured amount once as non-expiring wallet credits funded from your reseller wallet. Enter 0 to turn automatic grants off; disabling prepaid accounts pauses grants without removing your saved amount.
If your wallet cannot cover the full amount, the customer signup still succeeds with 0 welcome credits. The missed grant is not applied later automatically. The customer list and detail view show an action to transfer the originally requested amount manually after you fund your wallet. Changes affect only customers created after you save; existing customers never receive a retroactive grant.
Use `GET` or `PATCH /api/v1/platform/welcome-credits` for the same setting, or the MCP tools `get_platform_welcome_credit_settings` and `update_platform_welcome_credit_settings` in the `platform` toolset. Customer registration and detail responses include the public welcome-credit status and the requested and granted amounts.
Registration, prepaid access, the prepaid minute price, and prepaid defaults are also available through `GET` or `PATCH /api/v1/platform/default-limits`, or the MCP tools `get_platform_default_limits` and `update_platform_default_limits`.
## User view
Authorised reseller admins can open **User view** for one of their own customers to reproduce that customer's dashboard experience. A persistent banner identifies the customer and provides a clear return to the admin area. Each session is recorded in the audit history.
Use User view only for legitimate support and administration, and follow your organisation's access policy.
## Prompt templates
Create workspace prompt and flow templates in the Tenant Admin area. They are available to your reseller team and customer workspaces according to the visibility you choose.
End users can select a template while creating an assistant or from the system-prompt card, preview it, and apply a copy. Later template changes do not overwrite an existing assistant.
The customer-visible catalog is also available through `GET /api/v1/prompt-templates` and the MCP `list_prompt_templates` tool.
## Voice catalog
Choose which voices from the platform catalog your customers can pick from in the assistant voice picker. Turn individual voices on or off in an allow-list, and add further voices to the catalog when a customer needs one that isn't listed yet.
A voice switched off further upstream carries an **Upstream** marker and cannot be turned back on from here. A voice whose text-to-speech source has been retired platform-wide is flagged separately on its row, so you can replace it on the affected assistants or delete it from the catalog.
## Moving customer resources
Reseller admins can move supported resources between their own customer accounts, for example when handing an agency-built setup to the final customer. Review assistant assignments, numbers, tools, knowledge, and billing before completing a handover.
Every migration is recorded as a run with a reviewable history — who moved what, from where, to where — and a completed run can be rolled back from the same list.
# White Label API
Source: https://docs.famulor.io/admin/whitelabel-api
Manage your reseller platform's customers programmatically — list, register, mint tokens, log in, log out, and transfer credits
If you run a [white-label reseller workspace](/admin/tenants-and-whitelabel), the White Label API lets you manage your own end-customers programmatically instead of through the dashboard — build your own admin console, automate onboarding, run custom auth flows on your own domain, or wire credit top-ups into your billing system.
Every endpoint on this page requires API Access plus an API key created in your white-label workspace with the `platform:read` or `platform:write` scope and an owner or admin role. Results are always limited to your own customer workspaces. A key issued for a customer can use the REST API only while that customer workspace also has API Access; issuing or revoking a key does not grant the capability.
## Get platform users
`GET /api/v1/platform/users` lists your customers, newest first. Paginate with `limit` / `offset` (see [pagination](/api-reference/introduction#pagination)) and search by name or email with `q`.
```bash theme={null}
curl "https://your-domain.example/api/v1/platform/users?limit=20&q=jane" \
-H "Authorization: Bearer fam_XXXXXXXXXXXX"
```
## Register a platform user
`POST /api/v1/platform/users` creates a new customer account and workspace on your behalf. Two modes:
* **`invite` (default)** — no password required. The account is created without credentials; pair it with a login or token call below to actually get the customer (or your own frontend) into it.
* **`password`** — you choose an initial password (8+ characters) for the customer up front.
```bash theme={null}
curl https://your-domain.example/api/v1/platform/users \
-X POST \
-H "Authorization: Bearer fam_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe", "email": "jane@customer.example", "mode": "invite"}'
```
An email that's already registered anywhere on the platform fails with `409` — the message never reveals whether that account is inside or outside your own scope.
The registration response includes `welcome_credit` with `status`, `requested_credits`, and `granted_credits`. This lets your onboarding UI show whether the one-time welcome credits were granted or need a later manual transfer.
This is an authorised operator action. It remains available when hosted self-service registration is disabled.
## Configure registration and prepaid defaults
`GET /api/v1/platform/default-limits` returns the independent self-service-registration and prepaid-access controls, the prepaid extra-minute price in EUR, and the default limits for prepaid customer accounts. `PATCH` updates any subset of those settings.
```bash theme={null}
curl https://your-domain.example/api/v1/platform/default-limits \
-X PATCH \
-H "Authorization: Bearer fam_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"self_service_registration_enabled":false,"prepaid_accounts_enabled":true,"prepaid_extra_minute_price_eur":0.49}'
```
Self-service registration affects only account creation from the hosted login page on your verified custom domain. Existing customers can still sign in, and operator-created customers remain available. Prepaid access separately determines whether customers without a paid plan can use prepaid credits; when it is off, registered customers must choose a paid plan before using the platform.
The equivalent MCP tools are `get_platform_default_limits` and `update_platform_default_limits` in the `platform` toolset.
## Configure welcome credits
`GET /api/v1/platform/welcome-credits` returns the configured one-time amount, whether prepaid accounts and automatic grants are active, your current wallet balance, and the estimated number of new customers you can currently fund. `PATCH` updates the amount for future customers; 800 credits is the recommended starting point, and 0 disables automatic grants.
```bash theme={null}
curl https://your-domain.example/api/v1/platform/welcome-credits \
-X PATCH \
-H "Authorization: Bearer fam_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"welcome_credits": 800}'
```
Saving is allowed even when the amount is above your current wallet balance. If the wallet cannot cover a new customer's full grant, signup still succeeds with 0 welcome credits. It is not caught up automatically; use the balance transfer action when your wallet is funded. Existing customers are never credited retroactively, and later setting changes apply only to future customers.
## Log in a platform user
`POST /api/v1/platform/users/login` authenticates a customer with their own email and password and returns an access token on success. Use it to build a login form on your white-label platform instead of sending customers to the hosted login page. Failed sign-ins return the same generic `401` response and do not reveal whether an account exists.
```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/login \
-X POST \
-H "Authorization: Bearer fam_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"email": "jane@customer.example", "password": "correct horse battery staple"}'
```
This is the one White Label API operation with no MCP equivalent — credentials should never travel through an MCP tool call.
## Create a user token
`POST /api/v1/platform/users/{user_id}/token` creates an API key for a customer without needing their password — useful for a dashboard, onboarding flow, or approved automation acting on the customer's behalf.
```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/USER_ID/token \
-X POST \
-H "Authorization: Bearer fam_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"name": "Onboarding token", "expires_in_days": 90}'
```
The plaintext key is returned exactly once — store it immediately, it cannot be retrieved again. It belongs to the customer, not you: an omitted `scopes` grants full access for that customer, not just the scopes your own operator credential happens to have.
## Log out a platform user
`POST /api/v1/platform/users/{user_id}/logout` revokes the customer's active API keys and OAuth tokens in your customer scope. Use it to force a sign-out after an account is compromised or your relationship with that customer ends. Repeating the request is safe.
```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/USER_ID/logout \
-X POST \
-H "Authorization: Bearer fam_XXXXXXXXXXXX"
```
## Transfer balance
`POST /api/v1/platform/users/{user_id}/balance` moves credits between your workspace balance and a customer's:
* **Positive `credits`** — grants credits from your wallet to the customer (the standard way to provision a customer account).
* **Negative `credits`** — reclaims credits back from the customer into your wallet.
Either direction requires the source wallet to cover the amount — a wallet balance never goes below zero, and an attempted reclaim that exceeds the customer's balance fails outright instead of partially applying.
```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/USER_ID/balance \
-X POST \
-H "Authorization: Bearer fam_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"credits": 50, "note": "Onboarding credit"}'
```
## Manage API keys
Every workspace — including customer workspaces created through this API — can manage its own API keys through `/api/v1/api-keys` or **Settings → API Keys** in the dashboard. A user-owned credential can also mint a key directly for another same-brand workspace where that user is currently an owner or admin by calling `/api/v1/workspaces/{workspace_id}/api-keys`. That nested endpoint is a general multi-workspace capability and does not require white-label access.
```bash theme={null}
curl https://your-domain.example/api/v1/api-keys \
-X POST \
-H "Authorization: Bearer fam_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"name": "CRM integration", "scopes": ["calls:read", "leads:write"]}'
```
A key can never create another key with broader access than itself: `scopes` on a new key must be a subset of the calling credential's scopes. `GET /api/v1/api-keys` lists a workspace's keys without exposing their secrets; `DELETE /api/v1/api-keys/{id}` revokes one.
## MCP
Everything above is also available as MCP tools, grouped in the **`platform`** toolset (plus `list_api_keys` / `create_api_key` / `revoke_api_key` in the `settings` toolset). Connect with the toolset selector:
```text theme={null}
https://your-domain.example/mcp?toolsets=platform
```
| Tool | Maps to |
| ----------------------------------------- | ----------------------------------------------- |
| `list_platform_users` | `GET /api/v1/platform/users` |
| `get_platform_user` | `GET /api/v1/platform/users/{user_id}` |
| `register_platform_user` | `POST /api/v1/platform/users` |
| `get_platform_default_limits` | `GET /api/v1/platform/default-limits` |
| `update_platform_default_limits` | `PATCH /api/v1/platform/default-limits` |
| `get_platform_welcome_credit_settings` | `GET /api/v1/platform/welcome-credits` |
| `update_platform_welcome_credit_settings` | `PATCH /api/v1/platform/welcome-credits` |
| `create_platform_user_token` | `POST /api/v1/platform/users/{user_id}/token` |
| `logout_platform_user` | `POST /api/v1/platform/users/{user_id}/logout` |
| `transfer_platform_credits` | `POST /api/v1/platform/users/{user_id}/balance` |
There's no `login_platform_user` tool — logging in stays REST-only, for the reason above. The MCP tools accept either a `user_id` or an `email` to identify the target customer; REST always takes `user_id` from the URL path.
## Include services in one customer plan
In Plans, select the features and additional capacity to include in the recurring plan price. Customers see these services as **Included in plan**. Optional capacity purchases add to that allowance; an included feature is not charged again as a separate add-on. One-time services remain separate purchases.
The plan editor shows the platform fee, its tax, an estimated payment-cost reserve and your remaining contribution per customer. This is an estimate before your own operating costs and taxes. Annual offers use available annual service prices; otherwise the editor explicitly shows twelve monthly cost periods. Included credits remain a monthly allowance for both billing intervals.
Payment confirmation activates the purchased inclusions. A scheduled cancellation keeps access until the paid period ends. A failed renewal blocks paid access; a successful payment restores the purchased contract. Purchased credit balances remain separate. After cancellation, prepaid access follows your existing Free-account policy.
Duplicate a plan with existing subscriptions before changing its price or inclusions. The new plan starts inactive so you can review it before offering it to customers.
### Manage inclusions through the API
Use `GET /api/v1/reseller/plans` with `settings:read` to find your plans and available inclusion codes. Use `PUT /api/v1/reseller/plans/{id}/inclusions` with `settings:write` to replace inclusions on an eligible plan. Both operations require owner or admin authority in your Whitelabel workspace. The matching MCP tools are `list_reseller_plans` and `update_reseller_plan_inclusions`. These operations configure the offer; they do not charge customers or create paid subscriptions.
# Custom dashboards
Source: https://docs.famulor.io/analytics/custom-dashboards
Build your own analytics dashboards from live workspace data
A custom dashboard puts the numbers you care about on one screen — call volume, assistant performance, campaign outcomes, booking conversion, and more — instead of moving between separate pages to piece them together. Each dashboard is made of **widgets**, and you control what every one of them shows. Availability depends on your plan's **Custom dashboards** feature.
Prefer describing what you want in plain language? Select **Create with Milian** on any dashboard and [natural-language dashboards](/analytics/natural-language-dashboards) turns a written question into a previewable set of widgets you can add in one go — the fastest way to get a first dashboard going. This page covers building and editing widgets by hand.
## Creating a dashboard
Custom dashboards don't have their own index page — each one is its own icon in the sidebar. Select the **+** (New dashboard) at the bottom of that section, give the dashboard a name, and you land straight in it.
A new dashboard starts with the built-in overview: dashboard filters, headline numbers (conversations, completion rate, average duration, success rate, conversation spend), call activity, outcome mix, assistant performance, post-call intelligence, campaign funnel, a customer reach map, recent calls, and a row of module cards linking to the areas your plan includes. Every part of it is optional — see **Editing the layout** below for removing sections or clearing the overview entirely.
## Adding a widget
Select **Add insight** to open the widget editor. You can:
* **Start from a recommended insight** — ready-made widgets covering common questions (below), pre-filled with a sensible source, visualization, and grouping. Templates that need a plan feature you don't have show as **Locked**.
* **Build from scratch** — name the widget, then pick a data source, a visualization, and how to aggregate it. See [Dashboard widgets](/analytics/dashboard-widgets) for the full reference of what's available at each step.
| Template | Shows | Needs |
| --------------------- | --------------------------------------------------------------------- | ------------------ |
| Conversation activity | Call volume over time, compared to the previous period | — |
| Assistant performance | Conversation volume by assistant | — |
| Outcome mix | Successful, unsuccessful, and unknown call outcomes | Post-call analysis |
| Campaign funnel | Campaign progress from assigned leads through calls made to completed | Campaigns |
| Live conversations | Calls currently in progress | Live monitoring |
| Simulation quality | Passing tests and recurring evaluation failures | Simulations |
| Booking conversion | How conversations turn into confirmed bookings | Booking |
| Knowledge health | Stale, failed, and healthy knowledge sources | Knowledge |
Your own widgets sit under **Custom insights**, below the overview. A new one lands at the end of that group; move it into place from Customize mode (below).
## Editing the layout
Select **Customize** to enter edit mode. The dashboard name becomes editable, and each widget gets its own controls:
* **Edit** reopens the widget editor to change its source, visualization, filters, or name.
* **Width** sets how much of the row the widget fills — a quarter, a third, a half, two thirds, or full width.
* **Move left / right** reorders it among your other widgets.
* **Remove** takes it off the dashboard, after a confirmation. Rebuilding it later means adding the insight again, so note its settings first if it was fiddly.
The built-in overview sections have their own **Remove** control while customizing. **Restore removed** brings them back, **Start blank** clears the whole overview so only your own widgets remain, and **Restore overview** puts it back.
Select **Done** to leave edit mode. Layout changes save automatically as you make them.
Deleting a dashboard (the trash icon, in Customize mode) is permanent. The dashboard, its layout, and the insights you arranged on it are gone, and there's no undo.
## Filtering a dashboard
The filter bar at the top of a dashboard scopes everything below it: a date range (last 7, 14, 30, or 90 days, or a custom range) plus direction, status, outcome, sentiment, assistants, and campaigns. These apply on top of each widget's own configuration, so you can reuse the same widgets across a "last 7 days" view and a "last 90 days" view without rebuilding them.
## API and MCP
Dashboards and their widgets are fully manageable through the public API: `GET/POST /api/v1/dashboards`, `GET/PATCH/DELETE /api/v1/dashboards/{id}`, `GET/POST /api/v1/dashboards/{id}/widgets`, and `PATCH/DELETE /api/v1/dashboards/{id}/widgets/{widgetId}` (scope `dashboards:write`). The API also exposes `GET /api/v1/dashboards/{id}/analytics` for the computed data behind a dashboard. MCP: `list_dashboards`, `get_dashboard`, `create_dashboard`, `update_dashboard`, `delete_dashboard`, `get_dashboard_analytics`, `list_dashboard_widgets`, `create_dashboard_widget`, `update_dashboard_widget`, `remove_dashboard_widget`. See [Dashboard widgets](/analytics/dashboard-widgets) for the field reference.
# Dashboard widgets
Source: https://docs.famulor.io/analytics/dashboard-widgets
Reference for widget data sources, visualizations, aggregations, and filters
This page is the field reference for building a widget by hand in [Custom dashboards](/analytics/custom-dashboards) — what data you can pull from, how to visualize it, and how to filter it down.
## Data sources
| Source | Covers | Measures you can aggregate |
| --------------------- | -------------------------------------------------------------------------------- | --------------------------------------- |
| **Calls** | Phone calls, web voice and avatar sessions, widget live chat, and WhatsApp voice | Calls, Duration, Cost, Successful calls |
| **Assistants** | Per-assistant conversation counts | Assistants |
| **Campaigns** | Campaign delivery and funnel data | Campaigns, Calls made, Completed leads |
| **Usage and cost** | Credit spend over time | Conversation cost, Conversation minutes |
| **Simulations** | Assistant test runs and results | Simulation runs, Evaluation score |
| **Bookings** | Calendar bookings created through your assistants | Bookings |
| **Knowledge sources** | Knowledge base document and crawl-source health | Documents, Knowledge chunks |
## Visualizations
| Visualization | Best for |
| ------------------- | ---------------------------------------------------------------------- |
| **Number** | One headline figure — a total, a rate, an average |
| **Line** | A trend over time |
| **Area** | A trend over time, with the volume underneath emphasized |
| **Bar** | Comparing a metric across categories (assistants, campaigns, statuses) |
| **Donut** / **Pie** | A share of one total (outcome mix, sentiment split) |
| **Funnel** | Progress through ordered stages (assigned → called → completed) |
| **Table** | Row-level detail rather than a single aggregate |
Not every visualization applies to every source — the widget editor only offers the combinations that make sense for the source you picked. For example, Calls supports Number, Line, Area, Bar, Donut, Pie, and Table; Campaigns supports Number, Bar, and Funnel; Usage and cost supports only the time-based views (Number, Line, Area).
## Aggregations
| Aggregation | What it computes |
| ----------- | ---------------------------------------------------------------------- |
| **Count** | How many records match |
| **Sum** | Total of a numeric measure (for example, total duration or total cost) |
| **Average** | Mean of a numeric measure |
The editor only offers the aggregations that make sense for what you picked:
* Category-style visualizations (Bar, Donut, Pie, Funnel, Table) always count records.
* **Sum or Average** — call Duration and Cost, Conversation cost, Conversation minutes.
* **Sum only** — Calls made, Completed leads, Knowledge chunks.
* **Average only** — Successful calls (a success rate) and Evaluation score.
* Everything else counts records.
## Grouping and filtering
* **Group by** splits an aggregate into a trend or a set of categories. Calls can group by Date, Assistant, Campaign, Status, Direction, Sentiment, Success, or Post-call outcome; Campaigns, Bookings, Knowledge sources, and Simulations group by status (Bookings can also group by source); Usage and cost has no grouping.
* **Filters** narrow one widget without touching the rest of the dashboard. They're available on the Calls source, on the fields with a fixed set of values — Status, Direction, Sentiment, and Success — and the only operator today is **is** (an exact match), so a live-conversations widget filters Status **is** In progress.
* **Date range** sets the time window: last 7, 14, 30, or 90 days, with an optional comparison to the immediately preceding period of the same length.
* **Assistant scope** and **Campaign scope** limit a widget to one assistant or one campaign. Assistant scope applies to the Calls and Usage sources; campaign scope also applies to Campaigns.
## API and MCP
Widgets are fully scriptable through the public API — useful for building or migrating dashboards programmatically. The schema accepts a few more values than the in-product editor offers today; a widget built on a combination the dashboard can't render shows a short note in its place asking you to edit it and pick a supported one, so stick to the combinations above. A widget (`POST/PATCH /api/v1/dashboards/{id}/widgets[/{widgetId}]`, scope `dashboards:write`) has:
* `widget_type` — `statistic`, `chart`, or `table` (the broad shape; `visualization` picks the specific chart style within it)
* `visualization` — `auto`, `number`, `line`, `area`, `bar`, `stacked_bar`, `donut`, `pie`, `funnel`, `heatmap`, `table`, or `leaderboard`
* `data_table` — the data source (`calls`, `campaigns`, `assistants`, `leads`, `bookings`, `knowledge_bases`, `simulations`, `tools`, `phone_numbers`, `conversions`)
* `aggregation` — `count`, `sum`, `avg`, `max`, or `min` (`max` and `min` are API-only today)
* `column_name` / `group_by` — which field to aggregate or group by
* `conditions` — up to 20 filters, each a field, an operator (defaults to `equals`), and a value
* `compare_previous_period`, `rate_range` (`7d`/`14d`/`30d`/`90d`), `show_legend`, `show_values`
* `grid_w` (3–12) / `grid_h` (1–4) — layout size within the dashboard
MCP: `create_dashboard_widget`, `update_dashboard_widget`, `remove_dashboard_widget`, `list_dashboard_widgets`. See the [API reference](/api-reference/introduction) for the complete widget schema.
# Natural-language dashboards
Source: https://docs.famulor.io/analytics/natural-language-dashboards
Turn a plain-language analytics question into reviewable dashboard insights
Natural-language dashboards let you describe an analytics view in everyday language. Famulor prepares a preview, and nothing is added to your dashboard until you confirm it.
## Build a dashboard view
1. Open a [custom dashboard](/analytics/custom-dashboards).
2. Select **Create with Milian**.
3. Describe the metrics, time range, comparison, and filters you need.
4. Select **Preview insights** and review every proposed card.
5. Select **Add insights** to save the cards.
For example:
> Show success rate and average duration for outbound calls in the last 30 days.
Generated cards work like manually created [dashboard widgets](/analytics/dashboard-widgets). You can edit, resize, reorder, or remove them afterward.
## Supported questions
You can ask about conversation volume, activity over time, success rate, call duration, assistant and campaign performance, outcomes, status, direction, sentiment, and recent conversations. Supported time ranges include 7, 14, 30, and 90 days, with optional comparison to the previous period.
Filters use the values available in Famulor. If a request cannot be represented, the preview explains what to change instead of adding an uncertain result.
Dashboards always use data from the active workspace. Preview every proposed card before adding it, especially when your question contains several filters.
## Public API
Use `POST /api/v1/dashboards/{id}/natural-language` to generate a preview. Send the returned plan to `PUT /api/v1/dashboards/{id}/natural-language` to validate and save its widgets.
Both operations require the `dashboards:write` scope. See the API reference for the complete request and response schema.
# Agent Tools
Source: https://docs.famulor.io/assistants/agent-tools
A workspace-wide catalog of custom tools and pre-built connectors any assistant can call
Assistants act on the world through tools — actions they can take during a conversation. **Agent Tools** (`/tools` in the sidebar, under **Agents**) is where you build your own tools once and connect pre-built ones, so any assistant in the workspace can use them.
Agent Tools is workspace-wide: a tool lives here once and is assigned to as many assistants as you like. An assistant's own **Tools** tab is the per-assistant view, where you switch platform actions like call transfer, SMS, and end call on or off for that one assistant — see [Built-in tools](/assistants/built-in-tools).
## Agent Tools vs. Automations
Both are ways for an assistant to act on outside systems, but they run at different moments. A tool on this page is something the assistant reaches for itself, live, while it's already talking to someone — deciding in the moment that it needs to look something up or create a record. An automation is a fixed sequence of steps you (or Milian) design in advance, usually started by a background event like a call ending.
| | Agent Tools (this page) | Automations |
| --------------- | ------------------------------- | -------------------------------------- |
| Runs | Live, mid-conversation | Mostly in the background, on a trigger |
| Steps chosen by | The assistant, as it needs them | You or Milian, in advance |
The two meet in one place: an automation you make assistant-callable appears in **Installed** as an **Automation-managed** tool — listed here, but edited from the automation itself. For background workflows started by events like **On Call Completed** or a new contact, see [Automations](/automations/overview).
## Installed
Your workspace's own tools, grouped by type:
* **HTTP API tools** — call your own HTTP endpoint from any supported conversation channel, for example `book_appointment → POST https://…`.
* **MCP servers** — connect an external MCP server and allow every tool it offers, or select only specific ones.
* **Built-in** — platform capabilities such as call transfer, SMS, or end call, set up once here and reused across assistants. The same actions can be configured per assistant instead; see [Built-in tools](/assistants/built-in-tools).
Each tool is created once and can be assigned to several assistants — select **Assign** on a tool to see and change which ones use it. Editing a tool updates it everywhere it's assigned, and each row shows how many assistants use it (or **Unused**).
Rows also carry the tool's health: the result of its last run, and a warning when a connection stopped working. If an MCP server's sign-in expired, select **Reauthorize** on that tool — the connection is repaired in place, so assignments, allowed tools, and settings stay as they were.
## Agent Connectors
The **Agent Connectors** tab is a searchable app store of pre-built integrations — CRM, Calendar, Telephony, Automation, Productivity, Utilities, and Other apps, filterable by category or narrowed to MCP-only — that attach to an assistant as a callable tool in a couple of clicks instead of building an API tool by hand. Connect with an API key or an OAuth sign-in, depending on the app.
## Execution behavior
Every tool an MCP server exposes has its own **Execution behavior** section in the server's editor, controlling how that tool runs during a call or chat:
* **Allow cancellation** — lets the assistant cancel a running invocation. Cancellation can't undo a remote change the tool already made.
* **Duplicate calls** — what happens if the assistant tries to call the same tool again while it's still running: allow it, reject it, replace the running call, or ask the assistant to confirm first.
* **Speak progress updates** — read out progress text the MCP server sends while the tool runs. Only enable this for servers you trust, since that text becomes part of the conversation.
## Always available
Some tools are attached by the platform itself and never appear under **Installed** — you don't assign them, and they can't be removed:
| Tool | When it's available |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `get_current_time` | Always, on every call and chat. Returns the current date and time in the assistant's timezone (a campaign timezone overrides it). The system prompt also receives a "Today is …" line at call start, and `{{date}}` / `{{time}}` are available as variables. |
| `search_knowledgebase` | As soon as a knowledge base is attached to the assistant. |
| `submit_knowledge_gap_draft` | When a knowledge base is attached and knowledge-gap capture is enabled. |
| `check_availability`, `book_appointment` | When a calendar integration is connected under the assistant's **Integrations** tab. |
| Recall job tools | Only on a [Famulor Loop](/telephony/famulor-loop) Recall call. |
A prompt that tells the assistant to call one of these works without any tool assignment. Everything else — built-ins, API tools, MCP servers, connectors — must be installed and assigned.
## Max tool steps
Each assistant has its own **Max tool steps** setting, in its **Tools** tab — how many tool calls it may chain within a single turn before it has to answer without calling another tool. Range 1–20, default 3.
## Tool versions
Every change to a tool is versioned. Use the API or MCP to review a tool's history and restore an earlier version if a recent edit broke something.
## Managing tools
Workspace admins create, edit, and assign tools. Other members see a notice that tools are managed by workspace admins.
## Availability
Your plan's **Tools & MCP** limit caps how many tools the workspace can have installed at once. MCP servers additionally need the **Connect AI (MCP)** plan feature — without it, creating an MCP tool is refused. Both are shown under **Settings → Plan**.
## API & MCP
| REST | MCP tool | Scope |
| ----------------------------------------------------- | -------------------------------------------- | -------------------------------------- |
| `GET/POST /api/v1/tools` | `list_tools`, `create_tool` | `assistants:read` / `assistants:write` |
| `GET/PATCH/DELETE /api/v1/tools/{id}` | `get_tool`, `update_tool`, `delete_tool` | `assistants:read` / `assistants:write` |
| `GET /api/v1/tools/{id}/versions` | `list_tool_versions` | `assistants:read` |
| `POST /api/v1/tools/{id}/versions/{revision}/restore` | `restore_tool_version` | `assistants:write` |
| `GET /api/v1/tools/{id}/usage` | `get_tool_usage` | `assistants:read` |
| `POST /api/v1/tools/{id}/reauthorize` | `reauthorize_tool` | `assistants:write` |
| `GET/PUT /api/v1/assistants/{id}/tools` | `get_assistant_tools`, `set_assistant_tools` | `assistants:read` / `assistants:write` |
See [Tools & webhooks](/api/tools-and-webhooks) for request and response details.
## Next steps
Turn on call transfer, SMS, email, and other platform actions per assistant
Full API and MCP reference for building and assigning tools
# AI Quality Assurance
Source: https://docs.famulor.io/assistants/ai-quality-assurance
Run cohort QA over call transcripts — packs, credits, dashboard.
Analyze completed calls with structured insights across language and performance. Pick a **pack**, choose a **date range**, and review average score, resolution rate, trends, and top user questions.
Audio-level metrics (WER, overlapping speech) are not included in v1 — analysis is transcript-based.
## QA packs
| Pack | Focus |
| ------------------------- | ------------------------------------------------------------------- |
| Full QA | Score, resolution, hallucinations, sentiment, trends, top questions |
| Language & Hallucinations | Hallucinations, language quality, score |
| Resolution & Sentiment | Resolution, sentiment, top questions |
| Performance Trends | Score and resolution trends |
## QA credits
QA runs consume workspace credits based on LLM usage for each analysed call. The Usage page shows charges as **QA usage**. Cost breakdowns and markup are not exposed in the product UI.
## Availability
Requires **AI Quality Assurance** in your plan. This is distinct from per-assistant **[AI QA scorecards](/assistants/analysis#ai-qa-scorecards)**.
## UI
Open **AI QA** in the sidebar (`/qa`). Create a run, wait for the analysis progress, then open the Call QA Overview dashboard.
## API
* `GET/POST /api/v1/qa/runs`
* `GET /api/v1/qa/runs/{id}?include_results=true`
Scopes: `calls:read` / `calls:write`.
## MCP
* `list_qa_packs`
* `list_qa_runs`
* `get_qa_run`
* `create_qa_run`
# Post-call analysis
Source: https://docs.famulor.io/assistants/analysis
Automatically score sentiment, success, and extract structured data from every call
After a call ends, **AI analysis** can evaluate the transcript. It can rate caller sentiment, decide whether the call met a success criterion, and extract structured fields such as a callback number, order ID, or yes/no answer. The result is available in [History](/monitoring/history), the public API, and MCP.
## What analysis produces
For each analyzed call the result can include:
* **Sentiment** — `positive`, `neutral`, or `negative` (overall caller sentiment).
* **Success** — `true` / `false` (or `null` when success evaluation is off), plus a short **reason** explaining the verdict.
* **Data** — a map of the structured fields you defined, keyed by field name.
* **Analysis time** — when the result was produced.
Use sentiment and success filters in History or `GET /api/v1/calls?sentiment=&success=` to find matching calls quickly.
Analysis runs **after** the call and never affects the live conversation. If analysis is unavailable, the call and its transcript remain unchanged and no result is shown.
## Configuring analysis
Open the assistant's **Analysis** card and turn on the parts you need. Everything is optional; an empty configuration means no analysis runs.
Enabled by default. Turn it off if you don't need per-call sentiment.
Enable **Success** and describe, in plain language, what a successful call looks like — e.g. *"The caller booked an appointment"* or *"The caller confirmed their delivery address."* The result contains a boolean plus a reason.
Add fields to extract. Each field has a `name` (snake\_case, unique), a `type` (`string`, `number`, `boolean`, or `enum`), a `description` explaining what to extract (max. 500 characters), and — for `enum` — a list of `choices`. Every field is always attempted — there's no editor control to make one optional, though the API's `required` flag still exists in the schema.
### Example configuration
```json theme={null}
{
"sentiment": true,
"success": {
"enabled": true,
"criteria": "The caller booked an appointment"
},
"fields": [
{ "name": "callback_number", "type": "string", "description": "Phone number the caller wants a callback on" },
{ "name": "appointment_day", "type": "enum", "description": "Requested weekday", "choices": ["mon", "tue", "wed", "thu", "fri"] },
{ "name": "is_existing_customer", "type": "boolean", "description": "Whether the caller is already a customer" }
]
}
```
A resulting `calls.analysis` looks like:
```json theme={null}
{
"sentiment": "positive",
"success": true,
"success_reason": "Caller agreed to a Tuesday appointment and gave a callback number.",
"data": {
"callback_number": "+493012345678",
"appointment_day": "tue",
"is_existing_customer": false
},
"analyzed_at": "2026-07-05T09:12:44Z"
}
```
## Using analysis results
* **History filters** — filter the call list by sentiment and success to find, say, all negative calls that did *not* succeed.
* **Public API** — every call in `GET /api/v1/calls` and `GET /api/v1/calls/{id}` carries `analysis`, `sentiment`, and `success`. Filter the list with `?sentiment=negative` and `?success=false`.
* **MCP** — the same call fields are exposed through the MCP `list_calls` / `get_call` tools.
Re-running analysis on a past call — **History → Re-evaluate** — overwrites the stored sentiment, success, and extracted fields with a fresh result. It costs extra credits at the workspace's **History re-evaluate** rate; current rates are on the [Usage page](https://app.famulor.io/usage).
## AI QA scorecards
**AI QA scorecards** (Beta) score every finished call against your own quality checklist — a separate, complementary result from the sentiment/success/fields analysis above. Configure it in the same **Analysis & QA** tab as post-call analysis.
Off by default. The card is only shown once **Beta features** are switched on for the workspace under [Settings → Workspace](/settings/workspaces), and enabling it needs a plan that includes AI QA scorecards.
An overall score from 0–100; a call passes once it meets or exceeds this value.
Each criterion has a name, a weight (how much it counts toward the overall score), and a source:
* **LLM judge** — the AI reviewer reads the transcript and scores the criterion from a free-text description you write. Costs an extra evaluation per criterion.
* **Reuse success** — reuses this call's Analysis success flag (yes = 1, no = 0), at no extra cost.
* **Reuse sentiment** — reuses this call's Analysis sentiment (positive = 1, neutral = 0.5, negative = 0), at no extra cost.
Results appear in **History**, on the call's detail view. Configure scorecards the same way as analysis — through the assistant editor, `PATCH /api/v1/assistants/{id}`, or the MCP `update_assistant` tool.
This is different from the cohort-level [AI Quality Assurance](/assistants/ai-quality-assurance) tool, which runs a QA pack you choose against a batch of past calls on demand. Scorecards run automatically, per call, as it finishes.
## Configuring via the API
Use `PATCH /api/v1/assistants/{id}` or the MCP `update_assistant` tool to update the same analysis options programmatically. An empty configuration means analysis does not run. See the [API reference](/api-reference/introduction) for the request schema.
## Turn a real call into a simulation test
On a finished call in **History**, use **Create Simulation Test**. Famulor prepares a persona, script, and success criteria from the transcript and analysis, then opens the assistant's [Simulations](/assistants/simulations) panel for review.
The same action is available as:
* `POST /api/v1/assistants/{id}/tests/from-call` with `{ "call_id": "…" }` (`assistants:write`; Simulations must be included in the plan)
* MCP tool `create_assistant_test_from_call`
Clicking a transcript line in History jumps the recording to that moment.
# Built-in tools
Source: https://docs.famulor.io/assistants/built-in-tools
Give assistants safe actions for calls, messages, scheduling, and data capture
Built-in tools let an assistant take approved actions during a conversation. Configure them under **Assistant → Tools** and write a clear description of when each tool may be used.
If a tool is unavailable or misconfigured, the assistant receives a safe failure result and can continue the conversation.
## Available tools
| Tool | What it does |
| ------------------------- | ---------------------------------------------------------------------------- |
| **End call** | Ends the call after the assistant has completed the request and said goodbye |
| **Call transfer** | Transfers the caller to a configured phone number |
| **Warm call transfer** | Briefs a colleague before bringing the caller into the conversation |
| **Transfer to assistant** | Hands the live call to another assistant in the same workspace |
| **Send SMS** | Sends a text message to the caller or a configured number |
| **Send email** | Sends a fixed, templated, or assistant-written email |
| **Business hours** | Checks a weekly opening-hours schedule in the assistant's timezone |
| **Schedule callback** | Confirms a future callback and adds it to **Audience → Scheduled Callbacks** |
| **DTMF Input** | Sends keypad tones to navigate an external IVR or phone menu |
| **Collect Keypad Input** | Collects an exact number of keypad or spoken digits from the caller |
| **Collect payment card** | Securely captures a payment method into your connected payment account |
| **Set call variable** | Saves a value for later flow conditions, tools, emails, and webhooks |
Calendar availability and booking are configured through [Calendar booking](/assistants/calendar-booking).
## DTMF and keypad input
**DTMF Input** sends tones from the assistant to an external IVR. Configure `0–9`, `*`, `#`, or `A–D`, up to 32 characters. Leave the sequence empty when a prompt-based assistant should choose it during the call; a **Send DTMF** Flow node always requires fixed tones.
**Collect Keypad Input** receives keypad or spoken digits. Choose **Exact number of digits** for a fixed PIN or one menu choice (1–32 digits), or **Until the stop key** for a variable-length number. In the latter mode, `#` or `*` submits once the minimum length is reached; reaching the maximum also finishes. The stop key is not returned. New unconfigured tools accept 1–32 digits until the stop key. Existing tools with a saved digit count retain their exact length. The total timeout is 5–120 seconds. In the [Flow Builder](/flow-builder/overview), use a **Collect** node with type **Keypad or spoken digits**; its input-length mode and digit bounds control that step, while the assigned tool provides timeout and stop key. The default total timeout is 30 seconds, including the entry prompt; explicitly saved timeouts stay unchanged.
## Transfers
### Phone transfer
Choose a destination, transfer type (cold or warm), and the condition under which the assistant should transfer — describe it in as much detail as you can, since precise wording makes the trigger more reliable. You can also let the assistant determine the destination number dynamically instead of fixing it.
**Cold transfer** connects the caller straight through to the destination. Set a ringing timeout (15–80 seconds, 30 by default) before the attempt is considered unanswered.
**Warm transfer** briefs a colleague before connecting the caller — use it whenever the recipient needs context first. It needs a few extra settings:
| Setting | What it's for |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Outbound number | A workspace number with an outbound trunk, used to call the supervisor |
| Hold music | Plays to the caller while the supervisor is briefed |
| Hold message | Spoken to the caller right before they're placed on hold |
| Briefing initial message | The first thing the assistant says once the supervisor picks up |
| Summary instructions | What the assistant should tell the supervisor about the call |
| Share supervisor conversation with the AI | After a failed transfer, lets the AI use relevant supervisor consultation notes in the current call. The full consultation is always retained in the call record |
| Connected message | Spoken to the caller once the supervisor is connected |
| Ringing timeout | 5–120 seconds (30 by default) before the attempt times out |
**Fallback on failure** decides what happens if the colleague doesn't pick up: the assistant continues the conversation itself and offers alternatives, says goodbye and ends the call, or connects the caller straight through to a fallback number without a briefing. The AI always receives the provider-neutral failure status (busy, declined, no answer, or unavailable). Supervisor consultation notes are shared with the AI only when the setting above is enabled and the supervisor actually spoke.
### Transfer to another assistant
Hand off a live call to a different assistant in the same workspace — useful for language routing (detect the caller's language, transfer to a language-specialist assistant), a different compliance or consent path (move to an assistant configured for a different recording setup), or chaining specialized assistants (sales → onboarding, triage → expert) without provisioning a separate number for each step.
Choose the target assistant and a **Context Engineering Plan** — how much of the conversation it receives. Options run from the full message history down to a summary plus the last few messages (recommended), only the last few messages, a summary alone, or no prior context at all for a clean handoff. Optionally set a **message before transfer**, and choose whether the target assistant speaks its own initial message once it takes over.
The **Squad** view shows the resulting assistant-routing graph. Transfers to the same assistant are rejected, and a transfer limit prevents loops.
## Ending the call
Write the **End call** description as clearly as you'd explain it to a new hire — the tool only fires when its condition actually matches:
* **Simple** — end the call once all questions are answered and the caller no longer needs help.
* **More detailed** — also end after a successful booking, once the caller says goodbye, or once the conversation is clearly finished.
Cover the realistic paths you expect (success, goodbye, "nothing else needed") so the assistant doesn't hang up too early or drag a finished call out.
## SMS and email
For SMS, choose whether the recipient is the caller or a fixed E.164 number. The assistant must use a workspace number with outbound messaging enabled.
For email, choose a verified sender and one of three content modes:
* **Assistant-written** — creates the subject and body from the conversation.
* **Fixed** — always sends the exact configured content.
* **Template** — inserts call variables and stops if a required value is missing.
A successful send means the message was accepted for delivery; it does not guarantee delivery to the final inbox or handset.
## Business hours and callbacks
Business hours can contain one or more time windows for each weekday. The check always uses the assistant's configured timezone.
For callbacks, choose the destination and the maximum number of days customers may book ahead. The assistant must repeat the agreed time and obtain confirmation. Past dates and dates outside the allowed window are rejected.
## Payment-card collection
Connect your payment account under **Tools → [Agent Connectors](/assistants/agent-tools#agent-connectors)**, then add **Collect payment card** to the assistant or a Flow Collect node. The caller enters card details securely. Famulor never exposes the full card number or security code in conversation history.
Only use this feature where your legal basis, consent flow, and account permissions allow it.
Collecting a payment card costs extra credits at the workspace's **Card collection** rate; current rates are on the [Usage page](https://app.famulor.io/usage).
## Call variables and current time
**[Set call variable](/assistants/variables)** lets the assistant store approved values such as a company name or appointment preference. Limit the allowed keys when the assistant should only update specific fields.
Every assistant also has a current-time tool. It uses the assistant's timezone to resolve requests such as “tomorrow at 3” or “next Tuesday”.
## API and MCP
Built-in tools can be managed through `PATCH /api/v1/assistants/{id}` and the assistant tools in [MCP](/mcp/tools-and-scopes). Use `GET /api/v1/email-senders` or its MCP equivalent to list verified senders without exposing credentials.
# Calendar & booking
Source: https://docs.famulor.io/assistants/calendar-booking
Let assistants check availability and book appointments mid-call via Acuity Scheduling, Cal.com, Calendly, eTermin, HighLevel, or the built-in engine
Appointment scheduling is the classic voice-agent use case: the assistant checks open slots during the call, offers a few options, and books the one the caller picks. The platform supports this in two ways that can be combined freely:
1. **Calendar integrations** — connect an external scheduling provider (Acuity Scheduling, Cal.com, Calendly, eTermin, HighLevel) once, assign it to an assistant, and the assistant automatically gets booking tools for every call. Google Calendar and Outlook connect in the same place, but they feed the built-in engine's calendar sync rather than mid-call booking — see the note under the table.
2. **The built-in booking engine** — define your own event types with weekly availability and get a public, embeddable booking page at `/book/{workspace}/{slug}`, ICS invitation emails, and a `native` integration your assistants can book against. No external account required. See [Built-in calendar](/assistants/native-calendar) for the full picture.
## Providers at a glance
| Provider | Availability | Booking | Credentials |
| ---------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
| **Cal.com** | ✓ open slots of an event type | ✓ direct booking | API key (`cal_…`) + API endpoint (US, EU, or self-hosted), event type picked from a synced list |
| **Calendly** | ✓ available times of a selected event type | ✓ direct booking (paid Calendly plans), single-use scheduling link, confirmed cancellation | OAuth connect (one time) |
| **Acuity Scheduling** | ✓ live slots or class availability for a selected appointment type | ✓ direct booking, confirmed cancellation and rescheduling (series cannot be rescheduled) | OAuth connect (one time) |
| **eTermin** | ✓ live slots for a selected service + calendar/person | ✓ direct booking | Public Key + Secret Key (Account Settings → API), service and calendar/person picked from synced lists |
| **HighLevel** | ✓ live free slots of a selected calendar | ✓ direct booking | An existing HighLevel connection (from Automations → Connections) + calendar |
| **Google Calendar** | ✓ free/busy of a connected calendar, for the built-in engine | ✓ event creation with attendee invite, from the built-in engine | OAuth connect (one time) |
| **Outlook / Microsoft 365** | ✓ free/busy of a connected calendar, for the built-in engine | ✓ event creation with attendee invite, from the built-in engine | OAuth connect (one time) |
| **Native (built-in engine)** | ✓ computed from your event type's weekly availability | ✓ direct booking + ICS email | none — see [Built-in calendar](/assistants/native-calendar) |
**Google Calendar, Outlook, CalDAV, and ICS feeds are calendars for the built-in booking engine, not mid-call booking providers.** Connecting them makes their busy times — and for Google, Outlook, and CalDAV, event write-back — available to a [native event type](/assistants/native-calendar#the-built-in-booking-engine). Assistants cannot call them directly during a conversation. To book on those calendars mid-call, assign **My booking calendar** (that event type) to the assistant, or put a Cal.com, Calendly, Acuity, or HighLevel calendar in front instead.
**Calendly link mode**: Calendly's Scheduling API requires a paid Calendly plan. If your plan cannot book directly, set the integration's `booking_mode` to `link` — the assistant then agrees on a rough time with the caller and sends a **single-use scheduling link** by SMS or email (`link_channel`) instead of hard-booking. Integrations that hit the paid-plan restriction at call time are flagged with status `link_mode`.
## Connecting an integration
Go to **Booking → Integrations** and pick a provider card:
Paste your API key (Cal.com → Settings → Developer → API Keys) and pick the **API endpoint**: US (default), EU, or Custom for a self-hosted Cal.com instance. Select **Load event types** to fetch your events by name and duration — no need to copy a numeric ID from the URL. The integration also reads the event type's custom booking questions automatically; use **Refresh fields** if you change them later in Cal.com. Optional timezone override — make sure it matches the Cal.com event type.
Click **Connect with Calendly**, approve access, then choose an active event type by **name and duration**. One account connection can be reused by multiple integrations. If the event type has more than one location configured in Calendly, pick the one the assistant should use under **Meeting location**. Choose the booking mode, link channel, and Book/Cancel permissions.
Click **Connect with Acuity**, approve access, then choose an appointment type. Optionally select a specific calendar or person, or let the service choose any available calendar. Enable or disable Book, Cancel, and Reschedule for each integration.
Paste your **Public Key** and **Secret Key** (eTermin → Account Settings → API), then select **Load services** to fetch your services by name and duration. Picking a service loads only the calendars/persons eTermin offers for it — pick one and adjust the duration if it needs to differ from the service default. After the integration is saved, a **Web Push URL** appears: paste it into eTermin's **API → API & Web Push** settings (enable **Send Web Push**, prefer JSON format) so eTermin notifies the platform whenever an appointment is created, changed, or cancelled on its side. The editor then shows when the last event arrived — the quickest way to confirm the connection is live. An optional shared secret can be set on both sides and is checked as the `X-Webhook-Secret` header.
First connect a HighLevel account under **Automations → Connections** if you haven't already. Back in **Booking → Integrations**, choose **Connect HighLevel**, select that connection, then pick one of its active calendars. Book, Cancel, and Reschedule toggles are stored per integration, but assistants currently get availability and booking only for HighLevel — there is no HighLevel cancel or reschedule tool yet.
Click **Connect** and complete the OAuth consent. The connection can be reused by multiple event types in the workspace.
Pick one of your [booking event types](/assistants/native-calendar#the-built-in-booking-engine).
Every integration is **verified before it is saved**. Invalid credentials or event settings are rejected with a clear error. Secret values are never displayed again after saving.
Deleting the final integration that uses an Acuity account revokes its OAuth token through Acuity's disconnect endpoint and removes the local connection. An unused account can also be removed with **Disconnect account** in the Acuity editor; shared accounts cannot be disconnected until their remaining integrations are removed.
Existing personal-access-token integrations remain operational but appear as
**Legacy connection — reconnect with Calendly**. Reconnecting upgrades them to
OAuth and removes the PAT from the integration.
## Assigning to an assistant
Open the assistant's settings and tick the integrations it should use (or `PUT /api/v1/assistants/{id}/integrations`). Each assigned integration adds its own booking tools to every call:
| Tool | Type | What it does |
| -------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `check_availability(start_date, end_date?)` | read-only, interruptible | Fetches open slots for the date range and reads them out in the assistant's timezone (capped so the agent never recites 200 slots). |
| `book_appointment(name, email, start, notes?)` | write — runs with a filler phrase, not interruptible | Books the chosen slot. On success the booking start/ID are stored as call variables for flows, analysis, and webhooks. If the slot was just taken, the agent is told to offer another one. |
| `send_booking_link(email?, phone?)` | Calendly link mode only | Creates a single-use scheduling link and sends it via SMS or email. |
| `find_appointment(email, name)` | Calendly/Acuity management | Finds upcoming appointments for the selected event/appointment type. Both the exact booking email and full name are required. |
| `cancel_appointment(event_id / appointment_id, confirmed)` | write — not interruptible | Cancels only an event or appointment returned by `find_appointment` during the same call, after the assistant reads it back and receives explicit confirmation. |
| `reschedule_appointment(appointment_id, new_start, confirmed)` | Acuity management | Moves only an Acuity appointment returned in the same call, after availability was checked and the caller explicitly confirmed the new time. |
Every integration gets `check_availability` and `book_appointment`. The management tools are added only where the provider supports them: **Calendly** (find and cancel), **Acuity** (find, cancel, and reschedule, following the toggles you set), and the **built-in engine**, which adds a workspace-wide set that identifies the caller by phone number first and falls back to email plus full name. **Cal.com**, **eTermin**, and **HighLevel** calendars currently offer availability and booking only — the assistant can read slots and book on them, but not look up, cancel, or move an existing appointment during a call.
If more than one integration is assigned, tool names get the integration name as a suffix (for example `check_availability_sales`). Slots are always spoken in the **assistant [timezone](/assistants/timezone)** — set it in the assistant's settings.
Calendly bookings can't be rescheduled through its API — a caller who wants a different time gets a fresh `cancel_appointment` and `book_appointment` instead, or reschedules through the link in their Calendly confirmation email.
Tell the assistant **when** to book in its prompt, e.g.: *"Before offering any time, call check\_availability. Once the caller confirms a slot, call book\_appointment with their name and email."*
## Booking questions
Event types on the built-in engine can ask for more than a name and an email address. In the event type editor, the **Booking questions** section below the description lets you add custom questions — short text, long text, email, phone, address, URL, number, a single checkbox, checkbox group, radio group, select, multi-select, or multiple email addresses — each with its own label, an optional placeholder, and a required toggle.
**Name** and **Email** are collected on every booking and are always required. **Phone** is asked by default but optional — switch it to **Required** in the same section when every booking needs a callback number.
Every question gets an identifier (derived from its label, editable) that doubles as a URL parameter for prefilling the public booking page, e.g. `?name=Jane+Doe&email=jane@example.com&company=Acme` — repeat the parameter or use a comma-separated list for a multi-value field. A question can also be marked **Disable input if the URL identifier is prefilled**, which makes it read-only whenever that parameter is present — useful when an embedding page already knows the answer.
Assistants read these requirements automatically, no extra prompt needed: on the built-in engine, `check_availability` states in plain English what to collect before booking — for example *"To book, collect: full name; email address ([user@domain.tld](mailto:user@domain.tld)); phone number in E.164 format (e.g. +4915123456789); Company (required, short text)…"* (the message continues with a reminder never to confirm a booking before the booking tool succeeds) — and `book_appointment` requires exactly those fields, one parameter per question. It never reports a successful booking unless the underlying request actually succeeded. Providers other than the built-in engine ask for a full name and an email address.
Custom answers appear on the booking record — in the dashboard, under `answers` in `GET /api/v1/bookings/{id}` and the `get_booking`/`list_bookings` MCP tools, in the guest and host confirmation emails, in the ICS invite, and in every booking webhook payload (creation, cancellation, and reschedule).
## Plan gating
Your plan must include **Calendar integrations**. If it is not included, you cannot create integrations.
## Reconnecting an expired connection
Google Calendar, Outlook Calendar, Calendly, Acuity Scheduling, and HighLevel connections can expire — the account's password changed, access was revoked, or the stored refresh token lapsed. Famulor detects this the moment a refresh fails and flags the connection immediately, instead of waiting for a booking to fail.
* The affected row in **Booking → Integrations** shows an amber **Reconnect required** badge with a short reason, and a banner at the top of the tab counts how many connections need attention.
* Click **Reconnect** (↻) on the row to sign in again. Google, Outlook, Calendly, and Acuity return you to the same **Booking → Integrations** tab; for HighLevel the sign-in flow returns you to **Automations → Connections** instead — pick the same sub-account you originally connected, or reconnecting creates a separate connection.
* CalDAV/ICS calendars have no sign-in flow to restart: remove the calendar and add it again with a fresh app password.
Workspace owners and admins receive an email the moment a connection breaks, and a reminder every 7 days while it stays broken. This reminder is managed by your platform administrator. Via the API or MCP, the integration object exposes `connection_status` and `needs_reauth` so you can monitor connection health programmatically.
## Troubleshooting
Confirm the key is still active in Cal.com and that you pasted a live key (Cal.com's live keys begin with `cal_live_`), then select **Load event types** again. If you get an authentication error instead of an empty list, you likely picked the wrong API endpoint — an EU Cal.com account needs the EU endpoint (or Custom for a self-hosted instance), not the US default.
`book_appointment` needs a valid email address, because Cal.com rejects a booking without one. Spoken addresses ("anna at example dot com") and German umlauts are converted automatically before the request goes out, so most dictated addresses work; if what the assistant heard still isn't usable, it is told to ask again rather than booking. Tell it in the prompt to collect and confirm the email before booking, and to reuse an address you already hold as a [call variable](/assistants/variables) instead of asking twice.
The event type's only location in Calendly is a video-conferencing link (Google Meet, Zoom, Teams), and the voice agent can't generate meeting links. In Calendly, edit the event type and add **Custom** or **Phone Call → Inbound call** as a location — Custom is the safest choice and works in every case. If the event type ends up with more than one location, pick the right one under **Meeting location** in the integration.
In a Calendly organization, admin and owner accounts see every member's event types, including Round Robin and Collective events; a regular member account only sees its own.
A **Web Call** test runs without a phone number, so anything the booking flow derives from the caller's number (sending a scheduling link by SMS, looking an appointment up by phone) can't work the same way. Use **Test → Call** in the assistant header for a realistic run: the assistant dials a number you enter, or you dial its inbound number yourself.
Still stuck? Contact support with the integration's name, the error shown in the assistant editor, and a transcript of the call that failed to book.
## API & MCP
Everything above is available in the [public REST API](/api-reference/introduction) and as MCP tools at `https:///mcp`:
| REST | MCP tool | Scope |
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| `GET/POST /api/v1/integrations`, `GET/PATCH/DELETE /api/v1/integrations/{id}` | `list_integrations`, `get_integration`, `create_integration`, `update_integration`, `delete_integration` | `integrations:read/write` |
| `POST /api/v1/integrations/calendly/oauth-url` | `create_calendly_oauth_url` | `integrations:write` |
| `GET /api/v1/integrations/calendly/connections` | `list_calendly_connections` | `integrations:read` |
| `GET /api/v1/integrations/calendly/event-types?connection_id=…` | `list_calendly_event_types` | `integrations:read` |
| `POST /api/v1/integrations/acuity/oauth-url` | `create_acuity_oauth_url` | `integrations:write` |
| `GET /api/v1/integrations/acuity/connections` | `list_acuity_connections` | `integrations:read` |
| `GET /api/v1/integrations/acuity/appointment-types?connection_id=…` | `list_acuity_appointment_types` | `integrations:read` |
| `GET /api/v1/integrations/acuity/calendars?connection_id=…` | `list_acuity_calendars` | `integrations:read` |
| `GET/PUT /api/v1/assistants/{id}/integrations` | `get_assistant_integrations`, `set_assistant_integrations` | `integrations:*` or `assistants:*` |
Integration objects include `connection_status` / `needs_reauth`.
Event types, connections, and booking records for the built-in engine are covered in [Built-in calendar](/assistants/native-calendar).
# Assistant compliance review
Source: https://docs.famulor.io/assistants/compliance-review
Why an assistant gets blocked for fraud or abuse risk, and how to fix it or request manual review
Famulor checks assistant instructions and greetings for clear fraud or abuse risks whenever you save changes.
## When an assistant is blocked
Blocking is reserved for serious risks such as impersonating an unrelated bank, government body, or brand; caller-ID spoofing; credential theft; or similar scam intent.
A blocked assistant cannot handle phone, web, messaging, or email conversations, including calls started through API v1 or MCP. The assistant editor shows the reason and the content that needs attention.
When a new block is created, every current member of the affected workspace receives an email. The message uses the workspace's configured brand, app link and email sender.
## Fix and check again
Remove or rewrite the flagged content, then save the assistant. Famulor checks the updated version and restores the assistant when the issue is resolved.
## Request manual review
If you believe the content is legitimate, select **Request manual review** in the assistant editor and explain the intended use. The current version is reviewed, and the result appears in the editor.
You can also use:
* `GET /api/v1/assistants/{id}/compliance-review`
* `POST /api/v1/assistants/{id}/compliance-review` with `{ "reason": "..." }`
* the [MCP](/mcp/tools-and-scopes) tools `get_assistant_compliance_review` and `request_assistant_compliance_review`
If you edit the assistant while a review is pending, request a new review for the updated content.
# Guardrails & conversation quality
Source: https://docs.famulor.io/assistants/conversation-quality
Background audio, interruptions, filler phrases, idle and voicemail handling, ringing, consent, transcript privacy, and guardrails
These settings make the difference between "obviously a robot" and a conversation people stay in. All of them are per-assistant.
## Background audio
Complete silence sounds artificial on the phone. You can layer in:
* **Ambient sound** — office, city, forest, crowded room, or keyboard typing, with adjustable volume (or your own uploaded audio).
* **Thinking sound** — a subtle sound while the assistant is thinking — during the LLM wait and any tool calls — so processing never sounds like a dropped call.
Hold music is not part of this section: it's configured directly on the [warm transfer tool](/flow-builder/nodes#warm-transfer) (built-in track or your own upload), since it only ever plays while a supervisor is being briefed.
## Interruption handling
Callers interrupt — good assistants deal with it gracefully.
* **Allow interruptions** — on by default; the assistant stops speaking when the caller talks over it.
* **Minimum interruption duration** — ignores very short noises so a cough doesn't cut the assistant off.
* **Adaptive interruptions** — backchanneling like "mhm", "okay", or "right" is *not* treated as an interruption, so the assistant keeps talking through natural listener feedback but yields to a real interjection. In compatible realtime modes, select **Adaptive** under **Turn detection** to use this behavior.
* **Resume after false interruptions** — in supported modes, the assistant resumes its interrupted output when an apparent interruption produces no transcript during the two-second detection window. This control is disabled when interruptions are off.
As a starting point, outbound assistants usually work better when they're easier to interrupt — a caller who wants to jump in shouldn't have to talk over a pitch. Reception and front-desk assistants often benefit from a bit more stability, so a stray cough or background voice doesn't cut the assistant off mid-sentence.
## Noise cancellation and voice detection
Under **Conversation → Latency**, **Noise & background voice cancellation** is a single on/off toggle. It suppresses environmental noise and competing background voices before speech detection, with the appropriate audio model selected automatically for phone or web calls. Browser echo cancellation is separate and remains active independently of this assistant setting.
The **Custom voice detection threshold** control lives under **Conversation → Turn taking**. It changes how readily audio is classified as speech; it does **not** filter the audio. Auto uses 0.50 for pipeline and adaptive voice detection. Server voice detection uses 0.50 for web calls and 0.70 for phone calls. Lower values hear quieter speech but may react to noise; higher values reject more noise but may miss soft voices.
A live **latency waterfall** (STT / LLM TTFT / TTS TTFB / E2E) appears only in the studio web-call test panel — never in the public widget.
Telecom guidance (ITU-T G.114) targets one-way latency under 150 ms for a call to feel natural — a useful benchmark when deciding how aggressively to tune interruption and VAD sensitivity for your use case.
## Filler phrases & async tools
When a tool call (CRM lookup, availability check) takes seconds, the assistant can bridge the gap:
* **Speak-during text** — a fixed announcement at tool start ("One moment, I'm checking that…").
* **Filler phrases** — a rotating set of short phrases spoken during longer waits, with configurable initial delay and interval. Spoken only in pauses — they never talk over the caller.
* **Async tools** — mark a [tool node](/flow-builder/nodes#tool) as asynchronous and the conversation continues while the tool runs; the result is woven in once it arrives.
## Idle handling
Nobody wants a call that hangs forever in silence:
* **Idle timeout** — after this many seconds of silence, the assistant checks in ("Are you still there?").
* **Idle messages** — optional fixed phrases for those check-ins; leave empty for natural LLM-generated ones.
* **Max rounds** — after N unanswered check-ins, the assistant says goodbye and hangs up. This also protects your minute balance.
The same idle settings are available through `PATCH /api/v1/assistants/{id}` and the MCP `update_assistant` tool.
Independently, **max call duration** caps every call: when reached, the assistant wraps up politely and ends the call.
## Voicemail
This setting only decides what happens once answering-machine detection (AMD) reports a mailbox on an outbound call — not what happens when a call simply rings out unanswered.
* **Leave a voicemail message** — on: the assistant speaks a message, then hangs up. Off: the assistant hangs up immediately, leaving nothing.
* **Voicemail message** — the free-text message spoken via TTS when a mailbox is detected. Keep it short and include a callback number. Leave it empty and the greeting / first message is used instead.
Campaign calls use **On voicemail** and **Voicemail message** in Campaign Settings. These override the assistant for that campaign. Direct calls use [Assistant settings → Conversation → Voicemail](/assistants/conversation-quality#voicemail). An empty message falls back to the greeting. A message counts as left only when playback finishes. An unavailable mailbox cannot receive a message.
Automatic IVR navigation enables detection and presses menu digits when workspace Beta Features are enabled. With navigation off, an interactive receptionist remains on the normal conversation path. Call Screen handling takes priority. Turning campaign AMD off disables detection unless automatic IVR navigation or Call Screen handling is enabled.
## Ringing
Two independent timeouts control how long a call rings before something happens:
| Control | Range | Default | What it does |
| ----------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **Inbound ringing duration** | 30–120 s | 60 s | How long an inbound caller hears ringing while the assistant joins. Applies to both bring-your-own and platform-managed trunks. |
| **Outbound ringing duration** | 15–80 s | 45 s | How long outbound and WhatsApp voice calls ring before counting as no answer. |
This is separate from the [Call transfer](/assistants/built-in-tools#transfers) tool's own ringing timeout, which times a single transfer attempt rather than the original call.
## Consent
For jurisdictions requiring all-party consent (Germany: §201 StGB):
* **Consent announcement** — a configurable message played at call start (pre-generated, zero added latency).
* **Consent mode** — the caller agrees **verbally** or by **pressing a key** (DTMF).
* **On decline** — either continue the call, or end it politely.
* The consent result is stored with the call, audit-proof.
### What the consent covers
One announcement can cover two separate purposes. Tick them independently in the assistant editor:
* **Recording the call** — the recording starts *only after* consent, never before, and additionally
requires **Record calls**. Asked on **every** call, because each recording needs its own permission.
* **Remember callers** — a granted consent unlocks that caller's durable memory, so returning callers are
recognised without anyone approving them by hand under **Audience → Customer memory**. Asked **once**.
A declined consent is never stored as a permanent refusal: the caller is simply asked again on a later call.
The memory consent is re-asked only after the retention window under **Settings → [Memory](/assistants/memory)** has lapsed
without a call — the expired memory is deleted, so the next call starts fresh.
Each purpose must be named in the announcement. Consent to being recorded is **not** consent to storing a
customer profile — they are different purposes under GDPR. When you tick a purpose, the editor offers
matching wording in the assistant's language; leaving the text empty falls back to a purpose- and
language-aware default.
If **Record calls** is on while the announcement does not cover recording, the assistant refuses to record
and logs `recording_skipped_no_consent` — it will never record without a notice.
## Recording privacy: redaction and re-transcription
Two more controls sit next to recording, under **Settings → Privacy**.
### Redact PII in transcript
Selected categories of personal data are replaced with `[REDACTED:type]` before the transcript is stored — data minimisation, not just display masking. It applies to newly finished calls only; transcripts already stored keep their original text.
Turning it on starts with four categories selected — email address, phone number, IBAN, and credit card number. The full built-in list is much larger, spanning identity, contact, government-ID, financial, security-credential, and health information, and you can select any combination of it. Beyond the built-in categories, add up to 20 of your own named patterns (regular expressions) for anything specific to your business.
### Automatic re-transcription
Independently of the manual **Re-transcribe** action in History, **Re-transcribe recording** can run for every recorded call automatically. When it's on, each finished call's recording is transcribed again with a higher-accuracy engine once the call ends; the enhanced transcript appears in the call's detail view next to the live transcript. It requires **Record calls** to be on.
Automatic re-transcription bills per recorded minute (rounded up) at the workspace's **Re-transcribe** rate; current rates are on the [Usage page](https://app.famulor.io/usage).
## Guardrails
Deterministic safety rails on top of the prompt:
* **Manipulation → Prompt injection** — blocks attempts to bypass or override system instructions (jailbreak detection in the caller’s speech). Available on every plan, **on by default**; uncheck to opt out (`guardrails.input.jailbreak`).
* **Blocked topics** — subjects the assistant must refuse; matched output is replaced by your **refusal text** (Fallbacks & Guardrails).
* **Escalation keywords** — if the caller mentions one (e.g. "lawyer", "emergency"), the platform — not the LLM — triggers an immediate transfer to your **escalation number** (Fallbacks & Guardrails).
Topic and category filters are enforced in the output path, so they hold even when a clever caller talks the model around its prompt.
## Pronunciation & text cleanup
See [Models & voices → Speaking style](/assistants/models-and-voices#speaking-style): pronunciation dictionary, markdown/emoji filtering, speaking rate, and output volume.
## Troubleshooting
| Symptom | Try |
| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Noise cancellation eats caller speech in the transcript | Turn **Noise & background voice cancellation** off for that assistant (Conversation → Latency) and test again |
| Assistant answers while the caller is still speaking | Raise **Min. silence (VAD)** so it waits longer before deciding the turn is over |
| A cough or background voice stops the assistant mid-sentence | Raise **Min. interruption duration**; in supported modes, keep **Resume after false interruptions** on |
| Responses feel sluggish to start | Lower **Min. silence (VAD)** in small steps; only lower the voice-detection threshold if quiet speech is being missed |
| A caller declines something mid-call and you want a human to take over | The built-in **On decline** setting only continues or ends the call — add a prompt rule that detects the decline (for example: "if the caller says they don't want to share personal data, transfer the call") and pair it with a [Call transfer](/assistants/built-in-tools#transfers) tool pointed at a team member |
Change one setting at a time and re-test with a realistic call — small, isolated changes are much easier to judge than several at once.
# Engine modes
Source: https://docs.famulor.io/assistants/engine-modes
Pipeline, realtime, half-cascade, and Translate — choose how a conversation works
The **Engine mode** setting selects how conversations work. Pipeline, Realtime, and Half-cascade are assistant modes that support prompts and flows. **Translate** interprets a conversation between two people and uses its own language and voice settings.
Your workspace plan can include Pipeline, Realtime, Half-Cascade, and Translate independently. Locked modes remain visible in the assistant editor and link to the Plan page. These controls apply when a voice call or Translate room starts; text-only messaging continues through the assistant's text conversation path.
## Pipeline (default)
Classic three-stage architecture: **speech-to-text → LLM → text-to-speech**. Choose each stage from the models available to your workspace.
* Full control: pick STT, LLM, and TTS independently, including fallback chains per stage.
* Widest model and voice selection, best multilingual coverage.
* Turn detection via a semantic turn model or voice-activity detection (configurable).
**Use it when** you want maximum control over quality, cost, and language behavior. This is the right default for production telephony.
## Realtime
A single **speech-to-speech** model listens and speaks directly — no separate STT or TTS.
* Lowest latency and very natural prosody (laughter, hesitation, tone).
* Voice selection comes from the realtime model.
* Turn detection can be robust, semantic, or adaptive when the selected voice mode supports it. Other voice modes manage turn timing automatically.
* Fewer knobs: voice library and per-stage fallbacks do not apply.
**Use it when** conversational feel matters more than fine-grained control — demos, concierge experiences, voice-first products.
## Half-cascade
A hybrid: a realtime model does the **listening and thinking** (text-only), while a separate **TTS voice** does the speaking.
Half-cascade has its own text-capable realtime model selection, independent of
the full realtime selection. Changing it never changes the separate TTS voice.
* Realtime-grade understanding and turn taking, combined with your chosen TTS voice — including cloned or brand voices.
* Output voice is configured exactly like in pipeline mode.
**Use it when** you want realtime responsiveness but need a specific voice the realtime model doesn't offer.
## Translate
A live interpreter for two people. The host chooses both languages and voices, then each speaker joins on the web or by phone. Each person hears the other speaker in their own language. A private guest invitation does not require an account.
Translate keeps prompt, flow, tool, knowledge, and memory settings stored for other modes, but does not execute them. See [Translate](/assistants/translate) for room setup, invitations, phone participation, voices, and usage.
## Realtime turn detection
For compatible realtime and half-cascade assistants, choose how the assistant decides that the caller has finished speaking:
* **Robust (VAD)** — responds after a clear pause. Fast and predictable.
* **Semantic** — waits until the caller seems to have completed their thought, even with a mid-sentence pause. **Response eagerness** controls how soon it answers.
* **Adaptive** — short acknowledgements such as "mhm" or "okay" do not stop the assistant, while a clear interruption lets the caller take over. You can also tune minimum silence, voice sensitivity, interruption duration, or disable interruptions.
Assistants that do not expose these choices continue to manage turn timing automatically. Existing assistants remain on **Robust (VAD)** until you select another mode.
## Reliability behavior
If the selected realtime or half-cascade setup is temporarily unavailable, the assistant uses a compatible fallback when possible so the live call can continue.
## Quick comparison
| | Pipeline | Realtime | Half-cascade | Translate |
| ---------------------- | --------------------- | ------------------------ | --------------------------- | ------------------------------------ |
| Latency | Low | Lowest | Low | As phrases are ready |
| Voice selection | Full library + clones | Model-native voices | Full library + clones | Compatible library voices + clones |
| Per-stage fallbacks | Yes | — | TTS side only | Stops if translation cannot continue |
| Multilingual switching | Yes | Model-dependent | Yes (output) | Chosen language pair |
| Best for | Production telephony | Natural-feel experiences | Realtime feel + brand voice | Human-to-human interpreting |
## Troubleshooting
### Losing context mid-call
The assistant asks for information already given, or seems to miss something said earlier. This is a comprehension issue, not an engine-mode dial. Keep the facts it needs in the [knowledge base](/assistants/knowledge-base) rather than only in the prompt, and in a flow, use `collect` nodes so captured answers become [call variables](/assistants/variables) the rest of the flow can reference instead of asking again. If your plan lets you pick the [language model](/assistants/models-and-voices) yourself, a stronger one also holds a long conversation together more reliably.
### Unnatural conversation flow
Awkward pauses, the assistant talking over the caller, or the exchange feeling robotic. Try Realtime or half-cascade for more natural prosody and turn-taking, tune [interruption handling and filler phrases](/assistants/conversation-quality) so waits get bridged instead of going silent, and revisit the turn-detection mode above if the assistant answers too early or too late.
### Repetitive responses
The assistant reuses the same phrasing or confirmation across a call. This comes from the prompt, not the engine mode — add an explicit instruction such as "vary your phrasing, don't repeat the same sentence twice" and test a few different conversation paths to see where it recurs.
As a starting point: **Realtime** for fast sales or qualification calls, **Pipeline** for support and detailed troubleshooting, **Pipeline with a flow** for lead qualification that needs structured data capture.
# Appointment booking
Source: https://docs.famulor.io/assistants/example-prompts/appointment-booking
Understands why the caller wants an appointment, picks the right type, and books it
Pairs naturally with [Calendar & booking](/assistants/calendar-booking): this prompt handles the conversation, and the connected calendar handles availability and the booking itself.
## What it does
* Asks why the caller wants an appointment and matches it to an appointment type
* Answers a couple of common questions directly
* Declines unsolicited sales pitches
* Requires a connected calendar to check availability and book
This prompt only works with a [calendar integration](/assistants/calendar-booking) assigned to the assistant — that's what gives it `check_availability` and `book_appointment`.
## The prompt
```text theme={null}
## Identity
Your name is Sophie, booking assistant for [Company name].
## Call flow
Ask why the caller wants an appointment, then pick the matching type:
- Initial consultation → 15 minutes
- Follow-up → 30 minutes
Before offering a time, call check_availability. Once the caller
confirms a slot, call book_appointment with their name and email.
If the caller tries to sell you something, politely decline.
## Frequently asked questions
Q: Do you have parking?
A: [Insert your answer here.]
Q: What are your opening hours?
A: [Insert your hours here.]
## Guidelines
- Ask one question at a time; keep responses short and conversational.
- Only end the call once the caller confirms they have what they need.
- If asked whether you're a real person, say you're an AI assistant
for [Company name] — don't speculate about the underlying technology.
```
## Set it up
Set up a [calendar integration](/assistants/calendar-booking) — or the built-in booking engine — and assign it to the assistant.
Paste the prompt above into **System prompt**, replace `[Company name]`, and fill in your real FAQ answers.
Update the appointment types and durations to your own, and add more if you offer them.
Use the editor's **Test** button and walk through a full booking, including a slot that's already taken.
See [Example prompts](/assistants/example-prompts/overview) for more starting points.
# First-level support
Source: https://docs.famulor.io/assistants/example-prompts/first-level-support
Triages a support request, answers common questions, and routes what it can't resolve
Combines the routing pattern from [Receptionist](/assistants/example-prompts/receptionist) with a first pass at technical triage — asking for a product or reference number before deciding where the call should go.
## What it does
* Asks for a product number on technical issues
* Answers a short list of common questions directly
* Routes by topic, with a fallback to message-taking if the transfer fails
* Declines unsolicited sales pitches
If you record calls, turn on the built-in [consent announcement](/assistants/conversation-quality#consent) rather than scripting a recording disclosure into the prompt.
## The prompt
```text theme={null}
## Identity
Your name is Sophie, first-level support for [Company name].
## Call flow
If the caller has a technical problem, ask for the product number.
If they don't have it, tell them where to find it (for example, on
the device label). If the caller tries to sell you something, decline
politely.
Route by topic:
- Wants a quote → transfer to Sales
- Wants to speak to a person → transfer to Reception
- Emergency → transfer to Management
If the transfer fails or no one answers, collect the caller's details
for a written follow-up, in this order:
1. Full address
2. First and last name
3. Callback number
4. A short summary of what they need
## Frequently asked questions
Q: Do you have parking?
A: [Insert your answer here.]
Q: What are your opening hours?
A: [Insert your hours here.]
## Guidelines
- Keep responses short and focused. Ask one question at a time.
- You don't answer detailed content questions — that's what routing
and the knowledge base are for.
- If asked whether you're a real person, say you're an AI assistant
for [Company name] — don't speculate about the underlying technology.
## Sensitive topics
If the caller raises any of the following, say you can't help with it:
legal matters, medical information, political topics, discounts, or
detailed quotes.
```
## Set it up
Paste the prompt above into **System prompt**, replace `[Company name]`, and fill in your real FAQ answers.
Add [Call transfer](/assistants/built-in-tools#transfers) for each destination, with a matching condition.
For anything beyond the short FAQ above, connect a [knowledge base](/assistants/knowledge-base) instead of growing this list indefinitely.
Use the editor's **Test** button to run through a technical issue, a sales pitch, and a failed transfer.
See [Receptionist](/assistants/example-prompts/receptionist) for the same routing pattern without the technical-triage step.
# Intelligent voicemail
Source: https://docs.famulor.io/assistants/example-prompts/intelligent-voicemail
Captures a caller's request and contact details for a callback, without trying to resolve it
Use this when you'd rather have a clean, structured message than let calls ring out unanswered. It asks what the caller needs, confirms it understood, collects contact details in a fixed order, then ends politely.
## What it does
* Asks for the caller's concern and confirms it back to them
* Collects name and a callback number in a fixed order
* Ends the call once it has what it needs — it doesn't try to resolve the request
* Refuses to discuss sensitive topics
If you record calls, turn on the built-in [consent announcement](/assistants/conversation-quality#consent) rather than scripting a recording disclosure into the prompt.
## The prompt
```text theme={null}
## Identity
Your name is Sophie. You take messages for [Company name] when no one
is available to answer.
## Call flow
Ask what the caller is calling about. Summarize it back and confirm
you understood correctly, then say you'll pass it to the right person.
Then collect, in this order:
1. First and last name
2. Callback number — confirm it's the best number to reach them on
Once you have both, end the call politely.
## Guidelines
- Keep responses short and focused — your only job is capturing the
request and contact details, not resolving it or giving advice.
- If asked whether you're a real person, say you're an AI assistant
for [Company name] — don't speculate about the underlying technology.
## Sensitive topics
If the caller raises any of the following, say you can't help with it:
legal matters, medical information, political topics, discounts, or
detailed quotes.
```
## Set it up
Paste the prompt above into **System prompt** and replace `[Company name]`.
Add matching fields under [Analysis](/assistants/analysis) — a request summary, name, and callback number — so every message is available as structured data after the call.
Add the [Send email](/assistants/built-in-tools#sms-and-email) tool and tell the assistant to send the message to the right inbox before it ends the call.
Use the editor's **Test** button and confirm the assistant ends the call once it has a name and a number.
See [First-level support](/assistants/example-prompts/first-level-support) for a version of this pattern that also tries a transfer first.
# Example prompts
Source: https://docs.famulor.io/assistants/example-prompts/overview
Ready-to-adapt system prompts for common assistant scenarios
Each page below is a complete, working system prompt for a common scenario — not just a snippet. Copy one into a new assistant, swap the placeholders for your own business details, and test it before it takes a real call.
The assistant editor offers the same kind of head start from the other direction: **Choose template** applies a ready-made prompt (and sometimes a whole flow) from your workspace's template library. Use these pages when you'd rather see the full text and adapt it by hand.
For the craft behind these prompts — how to structure one, write clear tool conditions, and get spoken details right — see [Prompt writing](/assistants/prompt-writing) and [Prompting for speech](/assistants/prompting-for-speech).
Greets callers, routes requests to the right team, and takes a message when no one is available.
Understands why the caller wants an appointment, picks the right appointment type, and books it.
Captures the caller's request and contact details for a callback, without trying to resolve it.
Triages a support request, answers common questions, and routes what it can't resolve.
Outbound scripts for a sales offer and a payment reminder, with objection handling built in.
Every template only needs light editing to go live: your company name, real transfer destinations, and the [tools](/assistants/built-in-tools) it should use.
# Receptionist
Source: https://docs.famulor.io/assistants/example-prompts/receptionist
Routes callers to the right team by topic, and takes a message when no one is available
A general-purpose receptionist prompt. It doesn't try to answer every question itself — it figures out what the caller needs, routes it to the right place, and falls back to collecting a message when a transfer doesn't work.
## What it does
* Identifies the caller's request and matches it to a destination
* Routes with [call transfer](/assistants/built-in-tools#transfers) by topic
* Falls back to structured message-taking if the transfer fails or goes unanswered
* Stays out of giving advice — its job is routing and data collection, not answering questions
If you record calls, turn on the built-in [consent announcement](/assistants/conversation-quality#consent) rather than scripting a recording disclosure into the prompt — Famulor plays and logs it automatically.
## The prompt
```text theme={null}
## Identity
Your name is Sophie. You are the receptionist for [Company name].
## Call flow
Understand the caller's request, then route it:
- Quote or pricing request → transfer to Sales
- Urgent matter → transfer to Management
- Everything else → stay with you (Reception)
If the transfer fails or no one answers, collect the caller's details
for a written follow-up, in this order:
1. Full address
2. First and last name
3. Callback number — confirm it's the best number to reach them on
4. A short summary of what they need
## Guidelines
- Use a warm, professional tone. Keep responses short and natural.
- Your job is limited to routing and collecting these details — don't
give advice or answer questions about the request itself.
- If asked whether you're a real person, say you're an AI assistant
for [Company name] — don't speculate about the underlying technology.
## Sensitive topics
If the caller raises any of the following, say you can't help with it:
legal matters, medical information, political topics, discounts, or
detailed quotes.
```
For a hard requirement, add the same list under **Blocked topics** in [Guardrails](/assistants/conversation-quality#guardrails) too — guardrails are enforced even if a caller talks the model around the prompt.
## Set it up
Paste the prompt above into **System prompt**, then replace `[Company name]` and the transfer destinations with your own.
Add [Call transfer](/assistants/built-in-tools#transfers) for each destination, and write a matching condition for when it should fire.
Add matching fields under [Analysis](/assistants/analysis) so the address, name, and callback number are saved as structured data after every call.
Use the editor's **Test** button to run through a quote request, an urgent matter, and a failed transfer.
See [Example prompts](/assistants/example-prompts/overview) for more starting points, including [First-level support](/assistants/example-prompts/first-level-support) for a similar routing pattern built around technical questions.
# Sales and collections
Source: https://docs.famulor.io/assistants/example-prompts/sales-and-collections
Outbound scripts for a sales offer and a payment reminder, with objection handling built in
Two starting points for outbound campaigns — a sales offer and a payment reminder — plus a simple framework for handling however the person responds.
## Sales offer
```text theme={null}
## Identity
You are calling on behalf of [Company name].
## Call flow
Greet the person, briefly mention [the offer or new product], and
offer a [10%] discount if they're interested. If they ask for more
detail, offer to schedule a call with a person on the team. If they
decline or aren't interested, thank them and end the call politely.
```
## Payment reminder
```text theme={null}
## Identity
You are calling on behalf of [Company name] regarding an outstanding
payment.
## Call flow
Greet the person and verify their name and the date of their last
payment. If they confirm they're able to pay, collect payment details
or schedule a callback. If they can't pay now, note the reason and
end the call politely.
```
Payment-reminder and debt-collection calls are subject to strict rules on timing, frequency, and required disclosures in most markets. Check [dialer, retries & compliance](/campaigns/dialer-and-compliance) and applicable regulations before running this kind of campaign.
## Handling the response
Give the assistant a simple framework for the three ways a call can go:
* **Yes** — provide the next detail, or transfer to a person to finalize.
* **No** — close respectfully and record the outcome as not interested.
* **Maybe** — offer a follow-up call, or send more information.
```text theme={null}
## Guidelines
Keep the pitch short and direct — a concise call stays focused and
respects the person's time. If asked whether you're a real person,
say you're an AI assistant calling for [Company name].
```
## Set it up
Paste one of the prompts above into **System prompt** and fill in your company, offer, or payment details.
Assign the assistant to an [outbound campaign](/campaigns/overview) with your contact list and calling schedule.
Add a success criterion and structured fields under [Analysis](/assistants/analysis) — for example whether the person agreed, and any reason they gave — so campaign results are easy to filter.
Use the editor's **Test** button to run through a "yes," a "no," and a "maybe" before the first real dial.
See the [Outbound playbook](/campaigns/outbound-playbook) for who to call, when to call, and what to measure around these scripts, and [Example prompts](/assistants/example-prompts/overview) for more starting points.
# iOS & Android call screening
Source: https://docs.famulor.io/assistants/ios-call-screening
Turn on Pre-Call Automation so your assistant answers the screening question and waits for a real person
Modern phones can screen unknown callers. iPhones on **iOS 26** with Call Screening enabled — and Android phones with Google's call screening — answer the call first and ask for the caller's **name** and **reason for calling** before the phone ever rings. Your assistant hears the screening service's question, not the human it's trying to reach.
Famulor handles this for you: turn on **Call screen handling**, and when a screening service asks who is calling, the assistant identifies itself with the details you set, then waits silently until a real person picks up. Only then does the actual conversation start.
This mainly affects **outbound calls** your assistant places to mobile numbers. Without a response to the screening question, the call may never be put through.
## Turn it on
In the assistant editor, open **Settings → Conversation → iOS / Android Call Screen Handling**. If the assistant uses a conversational flow, the same settings live on the **Pre-Call node** in the flow builder — both places edit the same configuration.
Switch on the **Call screen handling** toggle under **Pre-Call Automation**.
* **Agent name** — the name the assistant gives when asked who is calling. Left empty, it uses the assistant's voice name.
* **Company name** — where the assistant is calling from. Left empty, it uses your workspace name.
* **Reason for calling** — one short sentence, for example *"to schedule a follow-up appointment"*.
Once enabled, the assistant answers the screening prompt with name, company, and reason, then stays quiet until the recipient accepts the call and speaks.
## Tips
* **Keep the reason short** — a single clear sentence passes screening best.
* **Avoid double greetings** — the assistant introduces itself to the screener, so make sure its normal opening doesn't repeat the full introduction a second time when the human picks up.
## Test it
1. Enable **Call Screening** on an iPhone running iOS 26 (**Settings → Apps → Phone → Screen Unknown Callers**), or Google call screening on an Android phone.
2. In the assistant header, choose **Test → Call** and dial that number.
3. Check that the assistant states its name, company, and reason, waits for you to accept, and then starts the conversation normally.
Still failing the screening? [Contact support](/support) with the assistant's configuration and a transcript of the test call.
## Next steps
Structure and tighten the instructions your assistant follows
Fine-tune behavior and responses
# Knowledge bases
Source: https://docs.famulor.io/assistants/knowledge-base
Help assistants answer from your documents and websites
A knowledge base gives an assistant approved information about your products, policies, opening hours, prices, and other business topics. When a caller asks a related question, the assistant can use the most relevant parts of your content instead of guessing.
## How it works
Everything you add is split into short passages and indexed. During a conversation, the caller's question is matched against that index, and only the best-matching passages are handed to the assistant as background for its answer — not the whole document, and not the whole knowledge base.
That has one practical consequence: the assistant only ever sees the passages that matched. If the answer to a question is spread across three documents, or the condition that qualifies it sits in a different section than the fact itself, the retrieved passage may be true but incomplete. Writing each topic as a self-contained section is what makes retrieval reliable — see below.
## Create and connect a knowledge base
Open **Knowledge bases → New**, enter a name, and add a short description of the content.
Upload PDF, DOCX, HTML, or text files. You can also add text, document URLs, or a website source.
Each item shows its status. If an item cannot be processed, open it to see what needs to be changed.
Use **RAG Search** to ask real customer questions and preview the passages an assistant would find. Improve any document that comes back unclear or contradictory.
Select the knowledge base in the assistant editor. No prompt change is required.
## Write content that answers well
* Use a clear heading for each topic.
* Keep the facts and conditions needed for an answer in the same section.
* Put important numbers in text, not only in complex tables.
* Remove outdated or contradictory copies.
* Prefer one subject per document where practical.
* Watch latency on very large knowledge bases, especially many heavy PDFs — converting core content to text files usually processes and retrieves faster.
## Import a website
Add a website source with a root URL. You can limit it to selected path prefixes, exclude unwanted sections, and set the maximum number of pages to import.
Before saving, choose **Load pages** beside **Website URL** to preview crawlable same-host pages. The preview checks `robots.txt` and available sitemaps, does not index anything, and spends no credits. Review the suggested sections, then explicitly add a path to **Include paths** or **Exclude paths**; suggestions are never saved automatically.
Run the import once, or enable automatic synchronization to check the site again at your chosen interval. Only new or changed pages use import credits.
Give each auto-refresh source a custom name when you add it. This is the name shown under **Auto Refresh**; it does not change the website URL or connected folder. Choose **Edit** on the source later to rename it or change its refresh settings.
Choose **Load pages** on a website source to view paths whose indexing is complete. Loading this list only reads the current index; it does not refresh the website or use credits.
For API or MCP access, use `GET /knowledge-bases/{id}/crawl-sources/{sourceId}/pages` or `list_crawl_source_pages`. Both return only ready, indexed pages and never start a refresh or use credits.
To run the same pre-save preview through API or MCP, use `POST /knowledge-bases/{id}/crawl-sources/discover` or `discover_crawl_source_paths`.
Website imports:
* follow pages on the same host,
* respect website crawling rules,
* work best with pages whose main text is present in HTML, and
* skip unsupported or oversized pages.
If a site loads all meaningful text only after JavaScript runs, add its content as documents or direct text instead.
## Cloud drive sync
Add a Google Drive, OneDrive, Box, Dropbox, or SharePoint folder as a knowledge-base source that stays up to date automatically, the same way a website source does. Connect the account under **[Automations → Connections](/automations/overview)** first if it isn't connected yet — an OAuth sign-in, not a pasted key — then add the folder as a source and pick that connection. SharePoint additionally requires the document library's drive ID — a folder path alone isn't enough to list its contents.
Run a sync once, or turn on auto-sync to check the folder again on your chosen interval. Only new or changed files use sync credits.
Cloud drive sync is Beta: turn on **Beta Features** under **Settings → Workspace** before the cloud-drive options appear. It is gated by its own plan feature, separately from website crawling, and billed per synced file at twice the per-page website-crawl rate — listed as **KB cloud drive sync file** on the [Usage page](https://app.famulor.io/usage), where you can check your current rates.
For API or MCP access, use `GET`/`POST /api/v1/knowledge-bases/{id}/drive-sources`, `GET`/`PATCH`/`DELETE /api/v1/knowledge-bases/{id}/drive-sources/{sourceId}`, and `POST /api/v1/knowledge-bases/{id}/drive-sources/{sourceId}/run`, or the MCP tools `list_drive_sources`, `create_drive_source`, `update_drive_source`, `delete_drive_source`, `run_drive_source`.
## Self-learning FAQ (Beta)
The **FAQ (Beta)** tab appears once **Beta Features** is on under **Settings → Workspace**. Question-and-answer pairs can be written directly under **Entries** — a lighter alternative to uploading a document. Independently of that, the **Inbox** collects factual customer questions that did not have a useful knowledge result. Review a proposed answer, edit it, and select **Approve & publish** before it becomes part of the knowledge base.
Assistant-generated proposals are never published automatically. Depending on the assistant setting, Famulor can collect only the question, prepare a private draft, or share a clearly tentative answer during the conversation.
Select **+** immediately before the **Entries / Inbox** tabs to open a new FAQ and focus its question field. Closing the form keeps your draft. When questions need review, the numbered notice opens all pending questions in the Inbox, clearing its search and status filter. The notice counts questions awaiting review, not unread messages.
Use **Search FAQs** in **Entries** or **Inbox** to search all questions, answers and proposed answers in that section. Search ignores case and treats the text literally. Inbox status filters apply before results are split into pages of 25. The page controls show the matching total and let you move to the first, previous, next or last page. The Inbox badge always counts all open entries, including those outside the current search. Unsaved edits remain available when you search, change filters or move between pages in the same knowledge base.
For API access, use `GET /api/v1/knowledge-bases/{id}/faqs` with optional `search` (up to 200 characters), `status` (one or more comma-separated statuses), `limit` (1–200, default 50) and `offset` (default 0). For example, `?status=needs_answer,needs_review&search=opening%20hours&limit=25&offset=25` returns the second page of matching open entries. The MCP tool `list_faq_entries` accepts the same search and pagination options; its status filter accepts one value or an array of values. The API returns the matching total in `meta.pagination.total` and the total open count in `meta.pending`; MCP returns `total` and `pending`.
## Availability and limits
The number of knowledge bases and access to website import depend on your plan. If your plan's included number of knowledge bases isn't enough, buy additional slots from **Settings → Plan** as the **Extra Knowledgebases** add-on, priced per knowledge base per month. Current per-knowledge-base limits are:
| Resource | Limit |
| ---------------- | -------------------------- |
| Files | 25 files, up to 20 MB each |
| URLs | 500 |
| Text entries | 50 |
| CSV, TSV or XLSX | 1,000 rows and 50 columns |
Website imports are billed in credits per new or changed page, at the workspace's **KB crawl / auto-sync page** rate — current rates are on the [Usage page](https://app.famulor.io/usage). The source shows progress and any action needed if the available credit balance is exhausted.
## Tables: CSV, TSV, XLSX and Google Sheets
Upload a rectangular table with its column headings in the first populated row.
CSV supports comma or semicolon delimiters and quoted multiline cells; TSV uses tabs.
Use UTF-8, or UTF-16 with a BOM. Legacy XLS files must be saved as XLSX or CSV.
XLSX includes every sheet, including hidden sheets. Google Sheets use the existing
Drive connection and include every exported sheet; exports over 10 MB fail explicitly.
Existing unchanged sources keep their previous index until the source changes or is reimported.
Each result keeps the original cell values, column positions, file, sheet and row.
Duplicate or empty headings receive distinct positional labels. CSV row numbers
refer to logical records, including blank records; a quoted multiline cell is one record.
XLSX references use worksheet row numbers. Search can match an exact identifier or
find a row from its description. Quote a whole value to request exact matching.
Similar identifiers are never evidence for a missing identifier. Multiple matching
rows require clarification. Indexed values are snapshots, not live inventory or prices.
Tables are limited to 1,000 records including headings across all sheets, 50 columns,
20 sheets and 6,000 characters per rendered row. XLSX expansion is limited to 32 MB.
Merged cells and values beyond the header width are rejected; split separate tables
onto separate sheets. The original table file is retained. A failed replacement
keeps the previous searchable index and reports the error.
Formulas are not recalculated. Cached formula results are clearly marked unverified;
missing results and cell errors remain unavailable. Ambiguous date/number text is
preserved without guessing a locale. Verify those values in the source before answering.
Use `POST /knowledge-bases/{id}/search` or the `search_knowledge_base` MCP tool.
Natural-language search returns source references and positional column keys.
For complete-sheet filters or totals, pass a table query using those references:
rows, count, sum, minimum or maximum; at most five equality/range filters combined
with AND. Numeric and date ranges require an explicit type. Numeric totals reject
missing, ambiguous, formula or mixed-currency values in matching rows. Results
include the number of matching rows and indicate when the displayed rows are limited.
Never calculate a full-table total by adding the few excerpts returned by search.
Joins, arbitrary expressions, currency conversion and formula evaluation are unsupported.
### Retry an existing document
Use **Retry** on a document that failed to process. API clients can send
`POST /api/v1/knowledge-bases/{id}/documents` with only
`{"document_id":"44444444-4444-4444-8444-444444444444"}`. With MCP, call
`add_document` with the knowledge base ID and the same document ID. Omit new
content, a file URL, a name and a description when retrying.
Both perform the same synchronous retry as the UI. A cloud drive document is
downloaded again from its current source, even if its version is unchanged.
Only that file is processed and charged at the normal sync rate; other documents
are neither refreshed nor removed. Drive access, sufficient credits and an
available sync slot are required. The previous searchable index remains usable
if processing fails. Folder discovery checks at most 500 files; if the target
falls outside that limit, use a smaller source folder. Other source types retry
their retained file or website; an uploaded original that has already been
purged and has no remote source must be uploaded again.
The API returns HTTP 200 with the document ID, processed/total chunk counts and
whether text was truncated; MCP returns the same fields. Failures return an
error. Creating new content still returns HTTP 201. API access requires
`knowledge:write`; MCP accepts `knowledge:write` or the existing
`assistants:write` scope. Both require a workspace role allowed to write.
# Languages
Source: https://docs.famulor.io/assistants/languages
Single-language setup, multilingual assistants, and automatic language switching
Set the language an assistant listens for, add secondary languages so it can switch automatically as a caller's language changes, and choose a matching voice for each one.
## Setting the primary language
Each assistant has an **STT language** that tells the transcription model what to expect. Set it to the language your callers actually speak — it measurably improves recognition of names, numbers, and addresses.
For the assistant's *output* language, be explicit in the system prompt:
```text theme={null}
Always answer in German, regardless of the language the caller uses.
```
Turn detection supports a **multilingual semantic model** (default) that understands sentence boundaries across languages, plus an English-optimized variant and plain VAD.
## Multilingual assistants
For markets where callers switch languages (common in DACH: German, Turkish, English), configure **automatic language switching**:
1. Choose a **multilingual speech-recognition model** so the transcription follows the caller.
2. Add at least one **secondary language**. Automatic switching turns on as soon as a secondary language is present and turns off when the last one is removed.
3. Optionally map a **voice per language** — e.g. a German voice for `de`, an English voice for `en`. When the caller switches, the assistant answers in the new language *with the matching voice*.
The assistant also receives a prompt hint to respond in the detected language, so the LLM follows along without extra prompt engineering.
Per-language voice choices are available for **Pipeline** and **Half-cascade** engines because those [engine modes](/assistants/engine-modes) use a separate speaking voice. They are hidden for a pure **Realtime** speech-to-speech engine.
Switching the editor view to **Voice per language** does not change the assistant by itself. Choose a voice for a language to save an override; languages without one keep the assistant's main voice.
Keep the system prompt in one language (ideally English — LLMs follow English instructions most reliably) and state the answering rule explicitly: "Answer in the language the caller speaks."
## API and MCP
The same language and voice settings are available through `PATCH /api/v1/assistants/{id}` and the MCP `update_assistant` tool. Use `GET /api/v1/languages` to list supported ISO 639-1 / ISO 639-3 language codes; see the API reference for the request fields.
## Pronunciation across languages
The [pronunciation dictionary](/assistants/models-and-voices#speaking-style) applies in every language — useful for brand names that TTS voices mangle differently per language. Tenant admins can define a tenant-wide default map that merges with per-assistant entries.
## Post-call summary language
The **Conversation Summary** on a call detail is always written in the assistant's **primary language** — not in the language the call was held in. A German assistant that took a call in English still gets a German summary, so a history list stays readable in one language. Re-evaluating a call (History → Re-evaluate) uses the same rule.
Everything else stays in the original language: the transcript, recordings, and extracted analysis fields are never translated.
When you change the primary language, only **new** summaries follow it. Use **Re-evaluate** on an older call to regenerate its summary in the new language.
## Documentation vs. call language
Note that the platform UI language and the assistant's call language are independent: your team can operate an English dashboard while assistants speak German to customers, and vice versa.
The language catalog includes two-letter codes and three-letter codes where needed, such as `ceb` for Cebuano. Available choices depend on both the speaking model and speech recognition. A language in the catalog is not supported by every model; check the choices shown for your assistant. Voice quality, accents, and supported writing systems can vary by language.
# Cross-channel customer memory
Source: https://docs.famulor.io/assistants/memory
Carry consented customer context across voice, email, support, and connected messaging channels
Customer memory connects exact, verified identities to one [Audience contact](/audience/contacts) and maintains a compact conversation summary. A customer can therefore continue in another channel without repeating known preferences, agreements, or open items.
Memory is available for supported voice, SMS, messaging, email, and helpdesk channels. Anonymous browser visitors and unverified contact details cannot read or update customer memory.
A [verified web widget](/web-widget#verify-visitors-by-email-or-sms) can use memory with a current verified email or phone, separate visitor consent, and the selected **Web Chat** or **Web Voice** channel enabled in both workspace and assistant settings. Configure the two channels independently. Web and SMS memory are available only in root workspaces, including a reseller’s own workspace, and are excluded from reseller customer workspaces. This does not restrict ordinary SMS sending. A verified email never verifies a claimed phone number or automatically merges another address. Private and None variable values are never copied into shared contact attributes; only permitted observed conversation data can update memory.
## Identity safety
* Verified phone numbers, email addresses, and channel identities are matched only within the current workspace.
* Display names and transcript content are never used to merge contacts.
* Conflicting identities are never merged automatically.
* Business sender identities are not treated as the customer's identity.
* Email memory requires authenticated sender verification; the visible sender text or message body alone is not enough.
* Anonymous browser calls and chats do not participate in cross-channel memory.
## Configure the workspace
Open **Workspace Settings → Data → Memory** to enable memory, select allowed channels, require consent, and choose a rolling retention period. An assistant can narrow the workspace policy under **Assistant → Settings → Privacy → Caller memory** by selecting read channels, write channels, categories, and a scope.
Structured contact fields are separate from conversation memory. Under **Assistant → Automations → Variables → Lead attributes**, explicitly select the contact fields that assistant may use; selecting none shares no additional contact fields. Private supervisor consultation and transfer-failure context remain limited to the current call and are not added to caller memory.
Built-in caller fields such as name and email follow the assistant's **Caller memory** switch automatically and do not need individual controls. For custom variables created under **Automations → Variables**, use **Caller memory → Remembered variables** to choose one policy per variable:
| Variable policy | Behavior |
| --------------- | -------------------------------------------------------------------------- |
| **None** | Available only during the current call and not retained afterward |
| **Shared** | Stored in the consented workspace memory and available to other assistants |
| **Private** | Stored only in this assistant's consented memory |
Remembered variables use the same consent, channel, retention, staleness, and erasure rules as conversation memory. Lead attributes are already workspace contact fields and therefore remain shared. A **Shared** variable key identifies one workspace-wide datum: use the same key only when every assistant means the same thing by it.
Retention and staleness are separate, independently configured settings. **Retention** decides how long a memory record exists at all — every successful update renews the rolling window, or you can choose to keep records until manually deleted; once retention lapses, the record is deleted. **Staleness** is optional and off by default: enable it and choose a number of days without a successful memory update. Stale content is no longer injected or reused. A later eligible conversation can create fresh memory from that conversation, while the old content remains unavailable until retention cleanup removes it.
```mermaid theme={null}
stateDiagram-v2
[*] --> Active: memory record created
Active --> Active: successful memory update (renews retention)
Active --> Stale: no successful memory update for the chosen number of days
Stale --> Active: eligible conversation creates fresh memory
Active --> [*]: retention lapses (record deleted)
Stale --> [*]: retention lapses (record deleted)
```
| Scope | Behavior |
| ----------- | -------------------------------------------------------------------- |
| `workspace` | One complete summary shared across all assistants |
| `assistant` | One complete summary private to this assistant |
| `both` | Two complete summaries: one shared and one private to this assistant |
Every read, write, consent change, skip, and deletion is audited. **Audience → Memory** lets workspace admins grant or withdraw consent and erase all shared and assistant-scoped memories for a contact.
## API and MCP
* `GET/PATCH /api/v1/settings/memory` manages the workspace's allowed channels, consent policy, and retention period.
* `GET /api/v1/contacts/memory` lists customer memories.
* `GET/PATCH/DELETE /api/v1/contacts/{id}/memory` reads, updates, or erases a contact's memory. An update must provide the current revision; a stale revision returns `409`.
* Assistant updates can define the memory scope, read and write channels, allowed categories, and the `none`, `workspace`, or `assistant` policy on each custom variable.
Equivalent MCP operations follow the same permissions and return the same customer-facing data as the REST API.
Only retain customer context with a lawful basis. Explicitly denied consent always prevents memory reads and writes. Unknown consent also blocks when the workspace requires consent.
**Audience → Memory** has a compact search button. Open it to search contact names, phone numbers, email addresses, and currently visible shared summaries across all matching contacts. Search combines with the consent filter and applies before pagination. Private, expired, and stale content is excluded. Closing the search clears it. The list API accepts the optional `search` parameter (up to 200 characters), and the `list_customer_memories` MCP tool offers the same search.
# Milian Copilot
Source: https://docs.famulor.io/assistants/milian-copilot
In-app AI that builds and edits assistants in your workspace
**Milian** is the workspace copilot built into the dashboard and assistant editor. Use it to create, explain, and improve your workspace configuration.
To connect an external AI application such as Claude or ChatGPT, use the [MCP endpoint](/mcp/overview).
## Where to find it
| Surface | What you get |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| **Dashboard** (`/`) | A full chat panel in the middle of the dashboard — create assistants, draft automations, ask for help |
| **New assistant** | **Generate from prompt** (Suggested) — describe a use case; Milian drafts name, type, and system prompt |
| **Assistant editor** | Header **Milian** — improve greeting/prompt/flow; changes appear on the canvas; click **Save** |
## Agent types
Milian respects the same modes as the editor:
* **Single prompt** — a standalone instruction with no saved conversation flow
* **Conversational flow** — built on a saved or existing flow; the flow's Advanced / base system prompt applies to agent steps
* **[Translate](/assistants/translate)** — live interpretation between a host and a guest. Ask Milian to create a Translate assistant, choose both languages and voices, and manage its room. Translate requires your plan's support and uses its own settings; recording and asking both speakers for consent are separate choices.
## What you can ask it
Milian isn't limited to writing prompt text — describe what you want in plain language from the assistant editor:
* **Tone and content changes** — "make the greeting friendlier," "add our 30-day return policy," "add a rule for handling angry callers."
* **Troubleshooting** — describe what's going wrong ("calls sound cut off at the start," "it keeps re-asking for the phone number") and Milian proposes a fix to the prompt, flow, or settings.
* **Configuration for your use case** — ask which [engine mode](/assistants/engine-modes) or settings fit a scenario such as sales, support, or appointment booking, and Milian recommends a starting configuration.
You don't have to start from a blank prompt either: pick a [use-case template](/assistants/overview#use-case-templates) when you create the assistant, then ask Milian to adapt it to your business.
Be specific and make one change at a time — "mention a 10% discount for new customers" works better than "add discount info," and small, testable edits are easier to review than a full rewrite.
## Use cases
### Automatic call analysis & reporting
Milian can review your workspace's calls on its own, spot patterns and conversion bottlenecks, and save the complete analysis as an Excel file directly to your Google Drive — no manual export needed.
### More things Milian can do for you
Ask Milian to build any of these as a one-off task or as a recurring [Milian Mission](/assistants/routines):
* **Daily executive call summary** — review every call logged today and summarize volume, success rate, sentiment, average duration, and notable calls or errors.
* **Outbound campaign progress digest** — check all running campaigns and report leads, calls made, completion rate, and progress toward the goal.
* **Win-back messages for inactive customers** — scan booking history and send a friendly WhatsApp message to customers who haven't returned in a while.
* **Appointment reminders** — check upcoming bookings and message each customer shortly before their appointment starts.
* **Waitlist auto-fill** — when a booking is cancelled, offer the freed slot to the next matching customer on the waitlist.
* **Post-appointment review requests** — after a booking is completed, thank the customer and ask for feedback, in the language they used.
* **Resume a paused campaign automatically** — check outbound call limits and restart a paused campaign once they reset.
* **Phone number availability watch** — monitor the marketplace for a specific area code and notify you the moment a number becomes available.
These are starting points, not a fixed list — describe your own workflow to Milian and it will propose how to build it.
## Memory
Milian remembers what matters across chats so you don't have to repeat yourself. There are two scopes:
* **Personal** — private to you in this workspace: your preferred language, your role, how you like Milian to communicate.
* **Shared workspace** — facts about the business that every member's Milian knows: company name, website, industry, what you sell, locations, opening hours, timezone, the tone your assistants should have, a fixed e-mail for call reports, house rules for prompts (for example "no emojis"). Only editors can change shared facts.
Milian is deliberately selective: it keeps stable facts you state or confirm and skips one-off task details, anything your workspace inventory already lists, phone numbers, secrets, and caller data. Every fact expires 180 days after it was last confirmed.
Under **Settings → Milian** you control two switches and see everything Milian remembers:
* **Search and reference chats** — lets Milian look up details from your own earlier chats (kept for 10 days) when you refer to another conversation.
* **Generate memory from chats** — lets Milian distil durable facts automatically after a conversation. Switched off, Milian only remembers what you explicitly ask it to.
Delete a single fact with the trash icon, or clear your personal memory at once. You can also just tell Milian — "forget the opening hours" or "remember that we're closed on Mondays".
This is Milian's own memory of your workspace. It is separate from [caller memory](/assistants/memory), which is what your assistants remember about the people who call them.
## Reviewing changes
Milian's edits land directly on the assistant canvas — the prompt, greeting, or flow updates as you chat. Read through the result before you click **Save**; nothing is written to the live assistant until you save.
# Models & voices
Source: https://docs.famulor.io/assistants/models-and-voices
Choose models, preview voices, clone your own, and turn on reliable fallbacks
An assistant's models decide how well it understands the caller and how it sounds. The assistant editor is where you pick them, tune the speaking style, clone a voice of your own, and switch on fallbacks that keep a call going if a model fails mid-call.
## Model catalog
The assistant editor shows a curated catalog of models available to your workspace:
| Type | Purpose |
| ------------------ | ---------------------------------------------------------- |
| Language model | Understands the conversation and decides what to say or do |
| Speech recognition | Converts the caller's speech into text |
| Text-to-speech | Produces the assistant's spoken voice |
| Realtime | Listens and speaks in one low-latency model |
Availability depends on your workspace and selected [engine mode](/assistants/engine-modes). Models marked **Recommended** are good starting points; **Low latency** highlights options suited to responsive phone conversations.
When **Fallbacks & Guardrails** is included, you can choose models separately for pipeline, realtime, and half-cascade assistants. Otherwise, the assistant uses the recommended automatic selection.
## Temperature
In Pipeline mode, **Temperature** controls how closely the language model sticks to your prompt versus varying its wording. The slider runs from 0 — deterministic and on-script — upward to more creative, improvised replies. **0.5–0.8** is a typical range for phone conversations.
Treat it as final fine-tuning, not a substitute for a well-written prompt:
1. Finish the prompt first — role, goals, boundaries, tone.
2. Start low.
3. Raise it in small steps, only once the baseline sounds good.
4. Test and compare after each change.
Raise it when replies sound stiff or formulaic and the use case tolerates some improvisation. Keep it low when consistency, compliance, or precise wording matter more than natural variation.
## Voice library
Use the voice picker to filter by language and voice characteristics, then play a sample before saving.
The public REST endpoint `GET /api/v1/voices` and MCP tool `get_voices` return provider-neutral local selectors. Upstream voice IDs and supplier names are not exposed; pass the returned `id` directly as `tts_voice`.
* **Assistant voice** — the default voice for the assistant.
* **Voice per flow agent** — give individual [flow](/flow-builder/nodes) agents distinct voices.
* **Voice per language** — change the voice together with [automatic language switching](/assistants/languages).
* **Cloned voices** — when included in your plan, add a private custom voice and use it like a library voice.
When recording a sample to clone, use clear, high-quality audio with steady, natural delivery and no background noise — and only clone a voice you have permission to use (see [Voice cloning consent](/assistants/voice-cloning-consent)).
For API cloning, check `sample_constraints` from `GET /api/v1/voices/clone/capability` for how many samples are currently accepted (`max_files`, up to 3), the maximum size per sample (`max_bytes_per_file`), and the maximum sample length (`max_duration_seconds`, or `null` for no limit), prepare that many direct uploads with `POST /api/v1/voices/clone/uploads`, upload the samples, then submit the job with `POST /api/v1/voices/clone`. MCP offers the equivalent `get_voice_clone_capability`, `create_voice_clone_upload`, and `submit_voice_clone` tools. The dashboard, REST, and MCP paths share the same **Clone your own voice** entitlement, consent check, workspace capacity, and tenant isolation.
## Speaking style
The available controls adapt to the selected model. Depending on the voice, you may see:
* speaking rate and output volume;
* stability, similarity, or expressiveness;
* free-text style instructions;
* a pronunciation dictionary for names, abbreviations, and specialist terms;
* filters that prevent markdown and emoji from being read aloud.
Only compatible controls are shown and applied.
Pick the voice first, then tune one control at a time — stability, similarity, or rate — and listen to a realistic phrase from your actual call flow before changing the next one.
When the **Dynamic emotions** setting (Expressive Mode) is available for the selected voice, the assistant can adapt emotion, pacing, emphasis, pauses, and supported non-verbal sounds to the conversation. It applies to pipeline and half-cascade assistants; realtime speech models handle vocal expression natively. Availability depends on the selected voice, and unsupported delivery cues are not applied. Transcripts remain clean and do not include delivery markup.
## Speech recognition glossary
Open **Assistant settings → Voice → Speech recognition** to add customer, product, and proper names that should be transcribed accurately. The glossary affects the transcript; use the pronunciation dictionary separately when a term also needs a special spoken form.
If **Automatic term detection (Beta)** is available and enabled, the assistant can recognise additional terms for the current call. This may add AI usage. Detected terms are not added to your saved glossary.
## Fallback chains
**Fallback chains** is a single switch, not a set of choices you configure. Turn it on, and if the primary speech-recognition, language-model, or voice service times out, errors, or drops mid-call, the assistant automatically moves to a compatible backup so the conversation keeps going instead of dropping. Famulor selects and maintains which backup each chain falls through to — there's no picker for the backup models themselves.
Fallback chains ship with the **Fallbacks & Guardrails** add-on; check **Settings → Plan** for availability. Failing over doesn't add a separate charge on its own — a call that fails over still bills at the normal call-minute rate.
Test important assistants after changing models, voices, or languages. A short simulation is usually enough to catch pronunciation and timing differences.
# Built-in calendar
Source: https://docs.famulor.io/assistants/native-calendar
Famulor's built-in scheduling engine for booking appointments during calls — no external calendar account required
Famulor ships with a complete scheduling system of its own: event types with their own weekly availability, an embeddable public booking page, optional sync with a real calendar, and a signed webhook on every booking. Assistants book against it mid-call like any other provider. The external providers — Cal.com, Calendly, Acuity Scheduling, eTermin, HighLevel — are on [Calendar & booking](/assistants/calendar-booking).
## The native calendar
**Native** is Famulor's own booking engine — built directly into the platform rather than a third-party product you sign up for, and listed alongside the other calendar providers in [Providers at a glance](/assistants/calendar-booking#providers-at-a-glance). There's no external account, no API key, and no OAuth consent screen: define an [event type](#the-built-in-booking-engine) with its own weekly availability and it's immediately ready to assign to an assistant.
Native runs on the same **Calendar integrations** plan feature as every other provider listed under [Providers at a glance](/assistants/calendar-booking#providers-at-a-glance) — it is not a separate paid add-on on top of Cal.com or Calendly. Your plan still has to include that feature before you can create any event type or integration, native ones included. See [Plan gating](#plan-gating).
An assigned native event type gets the same `check_availability` and `book_appointment` tools as any other integration, with no third-party API in between: slots come straight from the event type's own availability windows, buffers, and notice rules. Native is also one of only two providers — Acuity is the other — whose assistants can find, cancel, and reschedule an existing appointment, and the only one of the two that needs no external account for it. See [Assigning to an assistant](/assistants/calendar-booking#assigning-to-an-assistant) for the full tool list.
### Calendar connections
Native works standalone on just its own weekly-availability rules, or you can connect a real calendar so its busy times are respected and — for most connection types — confirmed bookings get written back to it. Connect Google Calendar and Outlook under **Booking → Integrations**; add CalDAV or an ICS feed under **Booking → Event types → Calendars**. Either way, pick the connection on the event type's own **Calendars** field to actually use it.
| Connection | What it does | Setup |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Google Calendar** | Free/busy, plus creates and deletes the booking as a calendar event with an attendee invite | OAuth connect (one time) |
| **Outlook / Microsoft 365** | Free/busy, plus creates and deletes the booking as a calendar event with an attendee invite | OAuth connect (one time) |
| **CalDAV** | Free/busy, plus creates and deletes the booking as a calendar event — no attendee invite from the server, so the guest relies on the booking engine's own ICS confirmation email | Server URL + username + app password — presets for **Apple iCloud**, **Fastmail**, and **Nextcloud**, plus **Custom** for Zimbra, Baïkal, or any other CalDAV server; the calendar collection is discovered automatically |
| **ICS feed** | Free/busy only — read-only, nothing is ever written back | A secret ICS/iCal URL (`webcal://` accepted), e.g. Google Calendar's "Secret address" or Outlook's "Publish calendar" |
## The built-in booking engine
Create event types under **Booking** in the dashboard (or via API/MCP):
* **Name, slug, duration** — the slug is unique within the workspace and becomes part of the public booking-page URL shown in the editor.
* **Weekly availability** — time windows per weekday in the event type's timezone, e.g. Mon–Fri 09:00–17:00.
* **Buffers & rules** — buffer before and after each booking, minimum notice, how far ahead customers may book, and slot increment.
* **Calendar sync** (optional) — link a [connected calendar](#calendar-connections). Google, Outlook, and CalDAV connections have their busy times subtracted from the offered slots and get confirmed bookings pushed back as calendar events; on Google and Outlook the guest is added as an attendee, so the provider sends its own invite as well. An ICS feed only contributes busy times.
* **Booking questions** — custom questions asked on the public booking page in addition to the always-required Name and Email, plus an optional "require phone number" toggle. See [Booking questions](/assistants/calendar-booking#booking-questions) for the question types, the prefill URL parameters, and how assistants learn what to collect.
* **Host confirmation** — the guest always gets a confirmation email with an ICS invite. A second copy goes to the host: the Add-to-calendar account, a custom organizer email, or the event-type owner if no calendar is selected.
### Public booking page & embed
Each active event type has a workspace-branded public page at `https:///book/{workspace}/{slug}` — no login required. Select **Embed** in the event-type list and choose one of four options: an inline booking flow, a floating pop-up button, a pop-up opened by your own page element, or an email-safe link/button. HTML and React snippets are generated for the selected option, with light, dark, and automatic themes where applicable.
The HTML loader uses a neutral, non-secret booking key and is served from the same domain as the public booking page:
```html theme={null}
```
The inline container fills the available width and height. Give its parent an explicit height when you want the booking flow to match a specific section; otherwise the loader applies a safe minimum and grows with the booking content.
Floating buttons can sit in either bottom corner. Element-click embeds use delegated clicks, so they also work with multiple matching elements and buttons rendered later by a React or other single-page app. On larger screens, pop-ups follow the measured booking height and remain vertically centered. They become full-screen on small displays, respect safe areas, lock background scrolling, and return keyboard focus to the element that opened them.
Enable **Forward page parameters** when booking-field prefills or campaign attribution should carry from the host page into the booking flow. It is off by default; when enabled, authentication-shaped parameters are filtered. Never place secrets in a page URL.
The email embed loads current availability and lets you select up to five times. It generates plain email text and email-safe HTML time buttons, each linking to the booking form with that slot preselected; the slot is checked again before the form opens, so an unavailable time can never be booked from an old email.
On a verified whitelabel domain, both the loader URL and booking page stay on that custom domain and use its branding; customer-facing snippets do not contain platform branding. Existing embeds keep working after a workspace rename because old booking handles redirect to the current URL.
Visitors pick a slot in their own timezone, enter their name, email address, optionally a phone number, and answer any [booking questions](/assistants/calendar-booking#booking-questions) you configured, then receive a **confirmation email with an ICS calendar invitation** plus a cancellation link. The configured host receives a matching **New booking** email. If two people choose the same slot at once, only the first booking succeeds and the other visitor is asked to choose another time.
### Booking from calls
Connect the built-in booking engine to an assistant to place mid-call bookings in the same calendar and link them to the related call. You assign it exactly like an external provider — see [Assigning to an assistant](/assistants/calendar-booking#assigning-to-an-assistant).
### Webhooks
Give an event type a **Webhook URL** and Famulor notifies it whenever a booking on that event type is created, cancelled, or rescheduled. Saving the URL reveals a **Webhook signing secret** — shown once, so copy it before leaving the page.
Each delivery is a `POST` of `booking.created`, `booking.cancelled`, or `booking.rescheduled`, signed with an HMAC-SHA256 of the raw body in `X-Famulor-Signature: sha256=`. The `data` object carries `booking_id`, the event type's `event_type_id`/`event_type_slug`/`event_type_name`, `invitee` (`name`, `email`, `phone`, `timezone`), `start_time` and `end_time` (plus `previous_start_time` on a reschedule), `status`, `source` (`web`, `call`, or `api`), the originating `call_id` when the booking came from a call, free-text `notes`, and the visitor's [booking question](/assistants/calendar-booking#booking-questions) answers in every booking webhook payload.
See [Receive webhooks](/api-reference/integration-examples#receive-webhooks) for a full server example, including signature verification.
## Plan gating
Your plan must include **Calendar integrations** — the same plan feature that gates the external providers on [Calendar & booking](/assistants/calendar-booking). Without it, you cannot create event types, and public booking pages do not accept new bookings.
## API & MCP
Everything above is available in the [public REST API](/api-reference/introduction) and as MCP tools at `https:///mcp`. Provider integrations (Cal.com, Calendly, Acuity, eTermin, HighLevel) and assigning any calendar to an assistant are covered in [Calendar & booking](/assistants/calendar-booking).
`GET /api/v1/bookings` and `list_bookings` support event type, source and date filters. Use `view=upcoming|unconfirmed|recurring|past|cancelled` for the same booking views as the dashboard, or use an exact `status` filter; `view` and `status` are mutually exclusive.
| REST | MCP tool | Scope |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------- |
| `GET/POST /api/v1/booking-event-types`, `GET/PATCH/DELETE /api/v1/booking-event-types/{id}` | `get_booking_event_types`, `create_booking_event_type`, `update_booking_event_type`, `delete_booking_event_type` | `bookings:read/write` |
| `GET /api/v1/bookings`, `GET /api/v1/bookings/{id}`, `POST /api/v1/bookings/{id}/cancel` | `list_bookings`, `get_booking`, `cancel_booking` | `bookings:read/write` |
Cancelling a booking sends a `METHOD:CANCEL` ICS update, so the appointment disappears from the invitee's calendar automatically.
# System prompt vs. flow builder
Source: https://docs.famulor.io/assistants/overview
Two ways to define assistant behavior — and when to use which
An assistant can be driven in two ways: a **single system prompt** or a **visual flow**. Both use the same voice engine; the difference is how much structure you impose on the conversation.
## What makes up an assistant
Every assistant combines the same pieces, however you configure its behavior:
| Piece | What it controls |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Behavior** | A system prompt or a flow — see below |
| **Engine mode** | [Pipeline, realtime, or half-cascade](/assistants/engine-modes) — how it hears and speaks |
| **Model and voice** | The [language model, speech recognition, and voice](/assistants/models-and-voices) it uses |
| **Tools** | [Built-in actions](/assistants/built-in-tools) like transfers, SMS, or ending the call, plus [Agent Tools](/assistants/agent-tools) you build or install yourself |
| **Channels** | Where it's reachable — phone numbers, [WhatsApp](/channels/whatsapp), the [web widget](/web-widget), and more |
Once configured, assign the assistant to a phone number for inbound calls or to a [campaign](/campaigns/overview) for outbound.
## Single system prompt
The simplest setup: one prompt describes the assistant's role, knowledge, and rules; one **first message** defines the greeting. The LLM handles the entire conversation freely within those instructions.
**Best for:**
* FAQ and reception assistants ("answer questions, take messages")
* Assistants whose job doesn't branch into distinct phases
* Fast prototyping — you can rewrite a prompt in seconds
**Configuration:**
* **Agent type** — choose **Single prompt** or **Conversational flow** when creating the assistant or later under **Settings → General**.
* **System prompt** — role, tone, rules, and facts. Use **Choose template** on the canvas (Prompt mode) or when creating the assistant. Applying a template copies into the prompt (and optional first message); it does not keep a live link to the template. See [Prompt writing](/assistants/prompt-writing) for how to structure and tighten the prompt itself.
* **First message** — the opening line, spoken when the call connects.
* **Greeting mode** — `agent speaks first` (typical inbound) or `user speaks first` (the assistant waits; useful for outbound where the callee says "Hello?").
* **Allow interruption** — optionally let callers interrupt the opening greeting. This is separate from conversation-level interruption settings.
* **Audio greeting** — optionally upload or record an audio file (mp3/wav/ogg/m4a, ≤ 5 MB) that plays at call start instead of the synthesized voice. The first-message text remains available for text channels and voicemail. Manage it from the Greeting card or through `POST`/`DELETE /api/v1/assistants/{id}/greeting-audio`.
* **Assistant picture** — optionally upload a PNG/JPEG/WebP image (≤ 1 MB) shown in the product UI instead of the default orb. Hover the avatar in the assistant header to upload or replace it, or use `POST`/`DELETE /api/v1/assistants/{id}/avatar`.
Keep the first message short — 5–10 seconds is plenty. Since it's spoken exactly as written, spell out numbers and punctuation the way they should sound (an ellipsis adds a natural pause). If you use a recorded audio greeting, have it professionally recorded and clone the same voice for the rest of the call, so the handoff from the recording to synthesized speech feels seamless.
## Use-case templates
The Create assistant gallery includes both prompt templates and complete flow blueprints. Flow blueprints show an expected outcome, compatible surfaces, and any setup you must finish after creation. Applying one copies its prompt, greeting, graph, and variables into the new assistant; the copy remains yours to edit and is not changed when the catalog template is updated. See [Start from a use-case template](/flow-builder/overview#start-from-a-use-case-template) for details.
An **Avatar-ready** label describes the intended web experience, not a special flow node. Configure the web widget and virtual avatar after creation. The assistant picture is only the static portrait shown in the product and is separate from the speaking avatar used during a web session.
## Flow builder
The [flow builder](/flow-builder/overview) turns the call into a graph: multiple specialized agents, condition branches, HTTP tools, data-collection steps, transfers, and explicit endings. The engine hands the conversation from node to node.
In the editor, switch to **Flow** (or create with Conversational flow). The **base system prompt** is edited under Settings → General → **Advanced prompt** (and collapsed on the canvas). Agent-node instructions are **appended** to that base — they do not replace it.
**Best for:**
* Calls with distinct phases (qualify → collect data → book → confirm)
* Reliable data capture (names, emails, phone numbers with built-in validation)
* Calls that must branch ("existing customer?" → different paths)
* Transfers with rules (warm transfer to sales only after qualification)
## Which should you choose?
| Situation | Recommendation |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------- |
| "Answer questions about X" | System prompt |
| "Collect a callback number, always" | Flow (a `collect` node validates it) |
| "Route support vs. sales" | Flow (a `condition` node branches) |
| "Call an API mid-conversation" | Either — flows give you `tool` nodes; prompt-only assistants can use [MCP tools](/api/tools-and-webhooks) |
| First prototype | System prompt, then graduate to a flow |
A flow's `agent` nodes can leave instructions empty — the assistant's system prompt (Advanced prompt) is used as the base. When an agent node has its own text, that text is **appended** to the system prompt, not substituted. Start with a prompt and add flow structure without duplicating the whole persona.
## Settings that apply either way
### Response behavior by channel
The assistant automatically adapts response length, tone, and formatting to the delivery channel: spoken calls stay natural and concise, live chat stays scannable, collaboration channels lead with actions, and email stays structured. No setup is required.
To refine one channel, open **Settings → Channels**, choose the channel, then expand **Advanced** and switch from **Automatic** to **Manual**. Manual instructions are added to the automatic profile; they never replace safety, language, tool-use, or delivery rules. Web Widget and WhatsApp expose their voice and text modes separately. Leaving Manual empty keeps Automatic active.
Regardless of mode, every assistant has: engine mode ([pipeline / realtime / half-cascade](/assistants/engine-modes)), model and voice selection, [knowledge base](/assistants/knowledge-base), [conversation-quality settings](/assistants/conversation-quality), recording and consent options, maximum call duration, idle timeout, optional tags, and a webhook URL for call results.
**iOS / Android Call Screen Handling** (Settings → Conversation, or the Pre-Call node in the flow builder) lets the assistant answer screening services (“Who’s calling?”) with a name, company, and reason, then wait for a person before giving the normal greeting.
## Version history
Every save snapshots the assistant's previous configuration. Open the **History** icon in the editor header to see the full list, newest first.
* **Rename a version** — give it a short, memorable label instead of the default "Version N".
* **Open a version** — read a plain-language summary of what it contains: prompt, models, voice, tools, channels, and more.
* **Restore a version** — the current configuration is snapshotted first, so restoring is itself undoable.
The same actions are available as REST and MCP:
| REST | MCP tool | Scope |
| ----------------------------------------------------------- | --------------------------- | ------------------ |
| `GET /api/v1/assistants/{id}/versions` | `list_assistant_versions` | `assistants:read` |
| `GET /api/v1/assistants/{id}/versions/{versionId}` | `get_assistant_version` | `assistants:read` |
| `PATCH /api/v1/assistants/{id}/versions/{versionId}` | `rename_assistant_version` | `assistants:write` |
| `POST /api/v1/assistants/{id}/versions/{versionId}/restore` | `restore_assistant_version` | `assistants:write` |
| `DELETE /api/v1/assistants/{id}/versions/{versionId}` | `delete_assistant_version` | `assistants:write` |
## Public demo link
Turn on **Public demo link** in the assistant editor to get a shareable URL anyone can open and talk to the assistant immediately — no login required. Calls placed through it bill your workspace's credit balance exactly like test calls, so keep an eye on usage if you share it widely.
Turning the toggle off stops the link from working. Turning it back on brings back the exact same link rather than issuing a new one, so a link you've already shared keeps working after a disable/re-enable.
The public demo link works on your workspace's white-label domain when one is configured. There's no REST or MCP equivalent — the dashboard toggle is the only way to turn it on or off.
# Prompt writing
Source: https://docs.famulor.io/assistants/prompt-writing
Structure, tighten, and iterate on the prompt your assistant follows on every call
Whether your assistant runs on a single system prompt or a [flow](/flow-builder/overview) built from agent nodes, the same craft applies: the model only knows what you tell it. A clear, well-structured prompt is one of the biggest levers you have over call quality — often more than which model or voice you pick.
This page is about *writing* good instructions. For where the system prompt lives, and when to reach for a flow instead of a single prompt, see [System prompt vs. flow builder](/assistants/overview).
## Structure your prompt in named sections
Don't write one long paragraph. Break the prompt into labeled sections, each with a single job. It's easier to write, easier to update later without breaking something else, and easier for the model to follow:
```text theme={null}
## Identity
Who the assistant is, which company it represents, what it specializes in.
## Style
Tone, formality, sentence length, how it handles humor or empathy.
## Knowledge
The facts it needs on hand — products, prices, policies, hours.
## Guidelines
Rules it must always follow (verify identity before sharing account
details, never promise a delivery date, one question at a time).
## Response patterns
Step-by-step handling for specific situations — pricing questions,
objections, what to say while a tool call is running.
## Limits
What it must never do, and what to say instead.
```
Sections can be reused across assistants and edited independently without touching the rest of the prompt.
## Be specific, not vague
"Be helpful and professional" gives the model nothing to act on. Pair every rule with a concrete example:
| Vague | Specific |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| "Help customers with billing questions." | "When a caller mentions a billing question, ask for their invoice number (format INV-XXXXX), then look up their account." |
| "Be friendly." | "Acknowledge what the caller said before answering — don't jump straight to the next question." |
| "Handle objections." | "If the caller says they're not interested, ask what would need to change for it to make sense — don't repeat the pitch." |
Avoid the opposite failure, too. Scripting every possible sentence removes the natural flow that makes a voice assistant pleasant to talk to — give rules and examples, not a transcript to recite.
## Handling what you didn't anticipate
Every prompt eventually meets a question it doesn't cover. Decide in advance how the assistant should react — pick one pattern (or combine them):
* **Default, then transfer.** "If you don't know the answer, say so plainly and offer to connect the caller with someone who does," then rely on [call transfer](/assistants/built-in-tools#transfers).
* **Ask a clarifying question.** "If the request is unclear, ask one short follow-up before deciding how to route it."
* **Check the knowledge base first.** If you've connected one, instruct the assistant to search it before falling back to a transfer — see [Knowledge bases](/assistants/knowledge-base).
## Writing clear conditions for tools and transfers
Every [built-in tool](/assistants/built-in-tools) and every [flow](/flow-builder/nodes) edge is only as reliable as the condition text describing when it should fire. Vague conditions produce vague behavior.
Two valid levels of detail for an end-call condition, depending on how much control you want:
* **Simple:** "End the call once all questions are answered and the caller no longer needs help."
* **Detailed:** "Also end the call after a successful booking, an explicit goodbye, or when the conversation is clearly finished — but never while the caller is still speaking."
The same precision applies to a transfer condition: describe exactly what the caller says or needs, not just "when appropriate."
Then say the same thing again in the prompt itself. A short section naming each tool and the moment it applies gives the assistant one ordered reference — worth the few extra lines whenever more than one tool could plausibly fire:
```text theme={null}
## Tools
- check_availability — before offering any appointment time.
- book_appointment — only once the caller confirms a slot, with their
name and email.
- Transfer to Sales — when the caller asks for a quote or pricing.
```
[Milian](/assistants/milian-copilot) can help draft and tighten this kind of condition text from a plain description of your process — describe what should happen, and ask for a short, checklist-style instruction you can paste straight into the field.
## How long should a prompt be?
* **Short (roughly 50–200 words)** — simple, single-purpose assistants.
* **Medium (roughly 200–500 words)** — several scenarios, each with a clear rule.
* **Long (500+ words)** — slows the model down and raises the odds it loses track of an earlier instruction.
If you find yourself pasting in a product catalog, a long FAQ, or detailed policies, move it to a [knowledge base](/assistants/knowledge-base) instead. Knowledge bases are searchable, don't add to every call's prompt length, and can be updated without touching the assistant.
## Common prompt-writing mistakes
| Mistake | Fix |
| -------------------------------- | ---------------------------------------------------------------------------- |
| Too vague ("be helpful") | Add concrete rules and example phrasing |
| Too rigid — every line scripted | Give guidelines and examples, not a transcript |
| Information overload | Move reference material to a knowledge base |
| Contradictory instructions | Re-read the prompt in order — a later rule should never fight an earlier one |
| No rule for unexpected questions | Add one of the fallback patterns above |
| Vague tool or transfer triggers | Name the exact situation, not "when appropriate" |
## Rolling out and iterating
No prompt is finished at launch — treat it as a living document.
Write clear instructions for your most frequent scenarios before chasing every edge case. A prompt that handles the majority of real calls well beats one that half-handles everything.
Use the editor's **Test** button for a quick voice or chat check, or set up [Simulations](/assistants/simulations) to run common scenarios, edge cases, and a difficult caller or two automatically before the prompt meets a real one.
Review new call transcripts closely right after launch — they show exactly where the assistant hesitated, guessed, or handled something the wrong way.
Add the specific example, rule, or fallback that would have fixed each miss. Small, targeted edits beat rewriting the whole prompt.
A few common symptoms and their usual fix:
| Symptom | Likely fix |
| ----------------------------------------- | -------------------------------------------------------------- |
| Generic, one-size-fits-all answers | Add specific examples and named scenarios |
| Required information keeps getting missed | List exactly what to collect, and in what order |
| Transfers happen too early or too late | Tighten the transfer condition's wording |
| States something that isn't true | Add an explicit "say you don't know rather than guessing" rule |
Full coverage of every possible call isn't a realistic target — language is too varied for that. Aim to shrink the gap steadily, and lean on [guardrails and a transfer to a person](/assistants/conversation-quality#guardrails) as the safety net for whatever's left.
See [Prompting for speech](/assistants/prompting-for-speech) for getting phone numbers, dates, and other spoken details to come out right, and [Example prompts](/assistants/example-prompts/overview) for ready-to-adapt starting points.
# Prompting for speech
Source: https://docs.famulor.io/assistants/prompting-for-speech
Write numbers, dates, and identifiers so they come out sounding right when your assistant reads them aloud
Your prompt doesn't just decide what the assistant says — it decides how spoken details land. A phone number typed as digits and a phone number spelled out for speech can sound very different once a voice reads them aloud. A few habits make the difference.
This page is about how you *write* the words in your prompt and knowledge base. To fix how a specific name or term is pronounced everywhere, use the [pronunciation dictionary](/assistants/models-and-voices#speaking-style) instead — the two are complementary.
## Write the spoken form directly
The most reliable technique is also the simplest: instead of relying on the model to reformat digits on the fly, give it the exact words to say.
**Phone numbers** — spell out each digit and group them for clarity:
```text theme={null}
When asked for the callback number, say:
"five five five, zero one three, four" —
not "5550134."
```
**Email addresses** — spell every character, and say the symbols as words:
```text theme={null}
Spell email addresses letter by letter. The @ is "at" and the . is "dot."
Example: name@company.com → "n, a, m, e, at, company, dot, com."
```
**Websites** — say recognizable words normally, and spell out any segment made only of letters:
```text theme={null}
Pronounce real words normally and spell out abbreviations letter by
letter. Always say "dot" before the top-level domain:
"yourcompany.io" → "your company, dot, i, o."
```
**Times and dates** — use a spoken format, never a raw timestamp:
```text theme={null}
Say times in words: "1:00 PM" → "one PM," "15:30" → "three thirty PM."
Never read a date as digits — "07/05" means two different days
depending on who's listening. Say "the fifth of July" instead.
```
## Pace long strings of digits
Long numbers — account numbers, IBANs, confirmation codes — are easier to follow when they're broken into short groups with a natural pause between them, rather than read as one unbroken string. A few short groups, separated by commas, are usually enough. Keep the grouping consistent within a prompt, and listen to the result before relying on it — pacing on punctuation can vary slightly by voice.
Don't overdo it. Long chains of pauses make speech sound unnatural — reserve them for information the caller genuinely needs a moment to write down.
## Giving the caller a moment
If a caller says they need a second — to grab an account number, for example — tell the assistant explicitly how to respond rather than leaving it to guess:
```text theme={null}
If the caller says "one moment," "hold on," or similar, reply briefly
("Take your time") and then wait for them to continue. Don't fill the
silence with another question.
```
## Test what it actually sounds like
Wording that reads fine on screen doesn't always sound right out loud. Use the assistant editor's **Test** button to place a real voice call and listen — especially after changing a voice, since pacing and pronunciation both depend on it.
See [Prompt writing](/assistants/prompt-writing) for structuring the rest of the prompt, and [Example prompts](/assistants/example-prompts/overview) for ready-to-adapt templates.
# Milian Missions
Source: https://docs.famulor.io/assistants/routines
Build versioned, scheduled, and event-driven work for Milian.
A **Mission** is a versioned task for the [Milian](/assistants/milian-copilot) copilot. It runs unattended on demand, on a schedule, or after a workspace event — no browser tab needs to stay open. Each run has a visible status, credit usage, and its own Milian transcript on the existing **Milian Missions** page.
The active Mission version fixes the trigger, filters, referenced resources, connected apps, allowed action groups, and run limits. Milian receives only that published scope during a run.
## Mission Studio (Beta)
Open a Mission on `/routines` to use the Studio tabs: **Overview**, **Trigger**, **Access**, **Runs**, and **Versions**. Existing schedule-only Missions continue to run unchanged. Their first Studio edit creates a version-1 draft.
One published version has exactly one trigger. The Studio supports manual and scheduled runs as well as call, conversation, message, email, booking, lead, inbound-webhook, CRM, and connected-app events. An AND/OR filter group can narrow the event by safe event fields.
Event Missions are a Workspace Beta feature. Turning Beta Features off pauses event Missions and marks them as needing attention; classic manual and scheduled Missions stay active.
## Schedule types
| Type | Fires | Fields |
| ------------ | ---------------------------------------------------------------------------- | ----------------------------------------- |
| **Manual** | Only when you (or Milian's `run_routine` tool) trigger it — never on its own | — |
| **Hourly** | Every hour, at a chosen minute | Minute (0–59, default 0) |
| **Daily** | Every day, at a chosen time | Time (`HH:MM`, default 09:00) |
| **Weekdays** | Monday–Friday, at a chosen time | Time |
| **Weekly** | Once a week, on a chosen day and time | Weekday (`0`=Sunday … `6`=Saturday), time |
| **Custom** | A 5-field cron expression (minute hour day-of-month month day-of-week) | Cron expression |
All schedules run against a **timezone** (default your workspace timezone) — the fields above are wall-clock time in that zone, including through daylight-saving transitions. A **Custom** cron schedule must fire at least **10 minutes apart**; a tighter interval is rejected when you save it. An **Hourly** mission fires once per wall-clock hour at its chosen minute; when a daylight-saving transition skips or repeats a wall-clock time, the mission resolves to the first valid occurrence.
## Required connections
Mission Studio grants individual connections already saved under **Automations → Connections**. A Mission refuses to run when a granted connection is missing, expired, disabled, or broken. Connections are rechecked immediately before each run.
## Inbound webhook secret
For an inbound-webhook Mission, a workspace owner or admin generates the delivery secret in Mission Studio. The browser creates a random 32-byte value and shows it only once; copy it immediately and send it in the `X-Automation-Secret` header. Later visits show only whether a secret is configured. **Rotate secret** replaces it immediately, so the previous value stops working. Neither REST nor MCP ever returns a saved secret or the internal managed Automation identity.
## Creating a mission
Milian Missions are **chat-first**: ask Milian directly and describe the goal, trigger, filters, resources, apps, and allowed actions. **New mission** opens this flow. Milian prepares a review, and you can continue in Mission Studio before activation.
In both Milian composers, type `@` to attach workspace context. Results include actual assistants, Missions, calls, contacts, and other workspace resources, plus only saved app connections and active Agent Tools. It never expands into the full app catalog. Assistant references show their avatar or the same orbit used on the Assistants page; phone numbers use their country flag; saved connections and Agent Tools use their vendor logo. Type `/` for commands that start a Milian review flow rather than mutating data silently.
Creating, updating, or deleting a classic Mission through chat still shows an **Approve / Cancel** confirmation card. Publishing a Studio draft additionally shows the immutable version review before activation.
## Managing a mission
The existing **Milian Missions** page lists trigger, status, active version, last run, next execution, credits, and attention state. Opening a Mission shows its Studio instead of a second page. Members may save drafts; workspace owners and admins may publish or pause. Viewer and Billing roles are read-only. **Run now** starts an off-schedule run; the transcript remains available from the row menu. A finished run can be retried manually: this always creates a separately marked run linked to the source run and never enables automatic retries.
Publishing creates an immutable version. Later edits stay in a draft while the active version keeps running. Restoring an older version creates a new draft; it never rewrites history.
## Background execution & transcripts
Every trigger creates a visible durable background run. Event runs are deduplicated and processed one at a time per Mission; additional events wait in FIFO order. The run appears as a Milian thread with the tools used. Run transcripts are kept for **10 days**.
Each mission also tracks its last run's outcome (succeeded, failed, or still running) and the next scheduled run, both shown on the Milian Missions page.
A run fails visibly when its owner loses access, the workspace is suspended, the plan or credits are unavailable, a connection was revoked, a capability boundary is crossed, or a run limit is reached. A possibly completed external mutation is never automatically repeated. Start a fresh manual run after reviewing the transcript.
Operational telemetry covers publications, trigger and run outcomes, queue and runtime duration, credits, tool-failure counts, and safe failure categories. It never includes prompts, secrets, raw event payloads, or raw tool output.
## Mission billing
Milian Missions capacity is sold as a monthly add-on unless included in the workspace plan. Every run uses normal Milian credits. A published version also sets maximum credits, tool calls, and runtime. Actual provider usage is always charged; a run that crosses its credit ceiling is marked failed and does not continue.
## Mission plan limits
The number of missions a workspace can have is its included plan capacity plus purchased Milian Missions units (`-1` = unlimited, `0` = unavailable without the add-on). Creating a mission past that capacity is rejected until you delete one or add capacity.
## API & MCP
Everything above is available in the [public REST API](/api-reference/introduction) and as MCP tools at `https:///mcp`:
| REST | MCP tool | Scope |
| ----------------------------------------------- | --------------------------------------------------- | --------------------------------- |
| `GET/POST /api/v1/routines` | `list_routines`, `create_routine` | `routines:read`, `routines:write` |
| `GET/PATCH/DELETE /api/v1/routines/{id}` | `get_routine`, `update_routine`, `delete_routine` | `routines:read/write` |
| `POST /api/v1/routines/{id}/run` | `run_routine` | `routines:write` |
| `GET /api/v1/routines/{id}/runs` | `list_routine_runs` | `routines:read` |
| `POST /api/v1/routines/{id}/runs/{runId}/retry` | `retry_routine_run` | `routines:write` |
| `GET /api/v1/routines/{id}/versions` | `list_routine_versions` | `routines:read` |
| `POST /api/v1/routines/{id}/versions` | `save_routine_draft` | `routines:write` |
| `POST /api/v1/routines/{id}/publish` | `publish_routine` | `routines:write` |
| `POST /api/v1/routines/{id}/pause` | `pause_routine` | `routines:write` |
| `GET/POST /api/v1/routines/{id}/webhook` | `get_routine_webhook`, `set_routine_webhook_secret` | `routines:read`, `routines:write` |
User-bound API keys and OAuth tokens keep that user's workspace identity. Service-account credentials without a user principal fall back to the workspace's oldest owner member.
## What a mission may do on its own
A mission runs unattended, so its published version is the approval boundary.
Grant only the action groups it needs: **Read**, **Write**, **Communicate**, and
**Call**. A concrete tool call is checked again against that group and against
its individual connection grant at the final execution boundary.
Billing and plan changes, roles and membership, credentials and secrets,
platform administration, destructive deletion, and subagent delegation stay
off-limits during the Beta.
Be deliberate with missions that read content you do not control — inbound
email, call transcripts, web pages, records from a connected app. Instructions
hidden in that text can influence the run. Give such missions a narrow prompt
and review their transcripts.
A Mission with the **Communicate** or **Call** grant can reach real people.
These are real actions with real effects, so keep event filters and grants as
narrow as possible and review run transcripts regularly.
# Assistant simulations
Source: https://docs.famulor.io/assistants/simulations
Test an assistant against an AI-played caller before it talks to a real one
Simulations let you check how an assistant behaves before a real caller does. Define a caller persona and a goal, and an LLM plays that caller against your assistant — either a fast text conversation or a real voice call — while a second LLM judges the result against the criteria you set.
## Where to find Simulations
Open an assistant, select the **Test** button in the header, and choose **Simulations**. The panel opens next to the editor, so you can adjust the prompt and rerun a test without leaving the page.
## Creating a test
Select **New test** and step through:
Begin blank, or apply a persona [Milian](/assistants/milian-copilot) suggested — see **Generate with Milian** below.
Name the test and write the caller's persona (identity and personality) in plain text.
Describe what the caller is trying to accomplish, for example: *"Your primary objective is to book a consultation for next week."*
Choose **Chat** or **Voice** mode, add the success criteria the judge should check, optionally list tools the assistant is expected to call, and set the maximum number of caller turns (up to 20, default 12).
Select **Generate with Milian** instead of starting from a blank test. Milian proposes a batch of ready-made personas and success criteria for the assistant — review them and create the ones you want with one click.
## Chat vs. voice
* **Chat** — a fast, text-only conversation between the caller LLM and your assistant. No call is placed, and it's the cheaper way to iterate on a prompt.
* **Voice** — places a real call: a simulated caller with a synthesized voice talks to your assistant over the same path a live call takes, so the whole speech pipeline gets exercised. It takes longer than chat, costs more, and shows up in **History** like any other call; pick the caller's voice when you switch to this mode.
## Creating a test from a real call
Open a finished call in **History** and select **Create Simulation Test**. Famulor writes a persona, goal, and default success criteria (accurate information, professional tone, proper resolution or routing) from that call's transcript and analysis, saves them as a new test, and takes you to that assistant's Simulations panel — review and edit it there before the first run. It's the fastest way to turn a real conversation that went wrong into a regression test. See [Post-call analysis](/assistants/analysis#turn-a-real-call-into-a-simulation-test).
## Running tests and reading results
Run one test at a time, or select **Run all** to work through every test in order. Each run reports:
* a **pass or fail per success criterion**, with the judge's reasoning;
* the full **transcript**, labeled Caller / Assistant;
* **tool calls** made during the run, checked against anything you marked as an expected tool;
* for voice runs, a **latency breakdown** — end-to-end, time to first LLM token, time to first spoken audio, speech-recognition latency, and perceived response time — plus a **View call** link to the resulting call in History.
Simulations is text- or audio-based conversation testing, not a validator for your prompt's wording alone — the caller LLM can improvise within the persona and goal you set, so a test result reflects how the conversation actually unfolds.
## Availability and cost
Simulations is a plan feature. If it isn't included, the panel says *Simulation testing is not in your plan* — compare plans under **Settings → Plan**.
Every workspace member can open the panel and read past runs; creating, editing, and running tests is limited to workspace owners and admins.
Simulations cost extra credits: every message in the run's transcript is charged at your workspace's **Call simulator message** rate — both in chat and in voice mode. Your current rate is listed on the **Usage** page under the credit rates (see [How usage is billed](/billing/minutes)), and each run appears there as a **Simulation run** transaction. Famulor checks your balance before a run starts and only charges for the messages actually produced. A voice run additionally consumes normal voice time for the call itself, since it exercises the full speech pipeline.
## API & MCP
| REST | MCP tool | Scope |
| ------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------- |
| `GET/POST /api/v1/assistants/{id}/tests` | `list_assistant_tests`, `create_assistant_test` | `assistants:read` / `assistants:write` |
| `PATCH /api/v1/assistants/{id}/tests/{testId}` | — | `assistants:write` |
| `DELETE /api/v1/assistants/{id}/tests/{testId}` | `delete_assistant_test` | `assistants:write` |
| `POST /api/v1/assistants/{id}/tests/{testId}/run` | `run_assistant_test` | `assistants:write` (voice mode also needs `calls:write`) |
| `POST /api/v1/assistants/{id}/tests/from-call` | `create_assistant_test_from_call` | `assistants:write` |
# Assistant timezone
Source: https://docs.famulor.io/assistants/timezone
How an assistant's IANA timezone shapes time-aware tools, variables, and business hours — and when a campaign overrides it
Every assistant carries a **timezone** — an IANA identifier such as `Europe/Berlin` or `America/New_York`, picked from a dropdown in the assistant settings. It defines what "now" means for the assistant, so *"tomorrow at 3 pm"* resolves to the caller's local tomorrow, not UTC.
The default is `Europe/Berlin`.
## What the assistant timezone affects
| Consumer | Effect |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`get_current_time` system tool** | The always-on [system tool](/assistants/built-in-tools#call-variables-and-current-time) returns the current date and time localized to this timezone — used whenever the model resolves relative dates ("next Tuesday", "in two hours") or books appointments. |
| **Time system variables** | `{{time}}`, `{{date}}`, `{{datetime}}`, and `{{weekday}}` (see [Variables](/assistants/variables)) are rendered in this timezone at call start. |
| **Business-hours tool** | The [`check_business_hours`](/assistants/built-in-tools#business-hours-and-callbacks) built-in tool evaluates its weekly schedule in this timezone — "open" always means open *locally*. |
## Campaign timezone override
Outbound [campaigns](/campaigns/overview) have their own timezone (used for calling windows). On a campaign call it **wins over the assistant's timezone** for that call:
```text theme={null}
effective timezone = campaign timezone (meta.timezone) ?? assistant timezone
```
So one assistant can serve campaigns in different regions and still tell each lead the correct local time. Calls without a campaign (inbound, single outbound calls, web) always use the assistant's timezone.
The timezone changes what the assistant *says and checks* about time — it does not shift call scheduling itself. Campaign calling windows are governed by the campaign's own timezone either way.
## Setting the timezone via API
Use `PATCH /api/v1/assistants/{id}` or the MCP `update_assistant` tool to change the assistant timezone programmatically. See the public API schema for the accepted timezone value.
# Translate
Source: https://docs.famulor.io/assistants/translate
Run a live interpreted conversation between two people, on the web or by phone
**Translate** connects two people who speak different languages. Each person hears the other person's translated speech in their own language. For example, Tobias speaks German and Aleksandra speaks Polish: Tobias hears German, and Aleksandra hears Polish.
Translate must be included in your current plan. The assistant editor keeps every engine mode visible; a locked mode opens its description and a link to the Plan page. The same workspace plan rule applies when rooms are created through the API or MCP.
## Prepare a conversation
1. Open an assistant and choose **Settings → Engine mode → Translate**.
2. Choose the spoken language and translation voice for both speakers. **Speaker 1** is the workspace user starting the conversation; **Speaker 2** is their guest.
3. Select **Open translation room**. The room opens in a new tab.
4. Choose how each person will participate, invite your guest, and select **Start conversation**.
Translate uses its own language and voice settings. Prompt, flow, tools, knowledge, memory, and ordinary assistant conversation settings are hidden in this mode. Their saved values remain available when you switch back to another mode.
## Choose voices
The voice selected for a speaker represents that speaker in the **other person's language**. If Tobias is Speaker 1, Aleksandra hears the Speaker 1 voice speaking Polish. Tobias hears the Speaker 2 voice speaking German.
Use an available library voice or an authorized [workspace voice clone](/assistants/voice-cloning-consent). The picker shows voices compatible with the listener's language. A private workspace voice can speak to a guest without giving that guest access to the voice library or the clone itself.
## Web and phone participation
| Option | What happens |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Web** | Join from a browser using a microphone and headphones. |
| **Call** | The host enters the person's international phone number. Starting the conversation calls that person. Either or both speakers can use a phone. |
| **Dial in** | With an active incoming number connected to the translation assistant, Speaker 1 can start the room, call that number, and enter the displayed six-digit room code, including any leading zero. |
**Call** requires a connected outgoing number. If none is available, call controls remain disabled. **Dial in** uses the incoming connection independently and does not require an outgoing number. Choose the country beside each destination number; the field includes its international dialing code. The guest can use Web or Call with any of Speaker 1's three options.
For dial-in, the assigned number is shown while you prepare the conversation. The six-digit code appears after you start the room and remains visible beside the number. Code entry has a 30-second window, including the spoken prompts, with at most three incorrect attempts. Entering the correct code before the room starts does not use an attempt; the call explains that the host must start the room first.
Each speaker uses one audio connection. When a person participates by phone, their browser becomes a transcript observer with its microphone and sound off. Leaving browser audio does not hang up a phone connection. The host can end the whole conversation with **End conversation**.
Use headphones for browser calls. If the browser blocks playback, select **Enable translated audio**. If microphone permission is denied, allow it in the browser's site settings and try joining again.
## Invite a guest
The host can copy a private invitation link or send an invitation by email. The guest does not need an account. Share the link only with the intended conversation partner.
Guests can join their assigned side and read the live transcript. They cannot change the languages or voices, place phone calls, send invitations, or end the whole conversation. A guest joining before the host starts sees a waiting screen.
## Follow the live transcript
The room displays each speaker's **Original** text beside its **Translation** as completed phrases become available. A browser can follow the transcript while its owner talks on the phone. Reconnecting reloads available conversation segments.
Completed original and translated phrases are saved in **History** when the room ends. Open an active Translate entry from History to return to its live room. Translate does not play the other person's original audio. If translation cannot continue, the conversation reports the interruption instead of forwarding untranslated speech.
## Recording and consent
Enable **Record calls** in the Translate assistant settings when you need an audio recording. Recording starts automatically when **Ask both speakers for consent** is off. When consent is on, each person first hears a recording notice in their configured language and answers verbally. Recording starts only if both people agree. If either person declines, the room follows the configured choice to continue without recording or end the conversation.
The saved audio represents Speaker 1's side of the interpreted conversation: Speaker 1's original speech and the translated audio heard from Speaker 2. History shows the recording alongside the bilingual transcript when it is available.
## Usage and charges
One shared conversation minute uses the normal voice rate plus the **translation surcharge** once. Having two speakers does not double this shared charge, and transcript observers add no charge.
Phone participation adds the applicable carrier charge for each actual phone connection: none for web-to-web, one for web-to-phone, and two for phone-to-phone. Separate attempts can create separate carrier charges. With your own carrier connection (BYOC), carrier charges remain with your carrier; the conversation's voice and translation credits still apply.
Your workspace's current rates are shown in **Usage**. Normal workspace credits and call limits apply to Translate.
# Custom variables
Source: https://docs.famulor.io/assistants/variables
Define per-assistant variables and inject live values — from the API, campaign leads, an inbound webhook, or system context — into prompts, greetings, and tools
Custom variables let you write an assistant once and personalize every call. Instead of hard-coding a name, an appointment, or an account number into the system prompt, you reference a placeholder like `{{customer_name}}` and supply the value per call — from your API request, a campaign lead, an inbound enrichment webhook, or the platform's built-in system context.
## Variable reference syntax
Reference a variable with double braces — the preferred, JSON-safe form:
```text theme={null}
Hi {{customer_name}}, I see your appointment is on {{appointment_date}}.
```
The legacy single-brace form `{customer_name}` is also resolved, but **only for keys that are actually known** (a defined or system variable). This keeps literal braces — for example JSON in a tool body — intact. Unknown single-brace text is left untouched; unknown double-brace placeholders become empty.
## Defining variables on an assistant
Each assistant carries a list of variable definitions. A definition has:
| Field | Required | Description |
| --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key` | yes | The identifier used as `{{key}}`. Lowercase letter first, then lowercase letters, digits, and underscores; 1–64 characters (`^[a-z][a-z0-9_]{0,63}$`). Unique per assistant. Cannot be a reserved [system variable](#system-variables). |
| `label` | yes | Human-readable name shown in the editor. |
| `description` | no | Note on what the variable is for. |
| `default_value` | no | Fallback used when no value is supplied at call time. |
| `example` | no | Sample value (editor/docs only, never sent). |
| `source` | no | Value-source policy: `manual` (default), `lead`, `webhook`, or `system`. `lead` explicitly grants this assistant access to the same-key registered workspace Custom Attribute and is validated against the current catalog. `system` is reserved for supported built-in defaults. |
Keys are validated on save: invalid format, a collision with a reserved system variable, a duplicate key, or a missing label are all rejected.
## Where variables are substituted
Values are substituted at call start, before the model or flow runs, in these fields:
* Assistant **system prompt**
* Assistant **first message** (greeting)
* Flow node **`start.greeting`**
* Flow node **`agent.instructions`**
* Flow **tool node** request **URL** and header **values**
* Flow **transfer node** destination **number** and **announcement**
* Flow **warm transfer node** destination **number**, **caller announcement**, and **briefing instructions**
* **Built-in tool texts** — tool **description**, transfer **announcement**, warm-transfer **hold message**, **connected message**, **briefing first message**, **summary instructions**, end-call **farewell**, assistant-transfer **pre-transfer message**, and payment-collection **prompt**
So a transfer node can route each call to a per-lead number like `{{handover_number}}`, supplied via campaign lead fields, the API call's `variables`, or the inbound variable-webhook — and a warm-transfer briefing can open with `Hallo, hier {{assistant_name}} von {{company}} — Anrufer {{caller_name}}`. See the [Node reference](/flow-builder/nodes) for what each flow field controls.
Spoken tool texts are substituted twice: once at call start with the resolved input variables, and again at the moment the tool runs — so values collected **during** the conversation (via `set_variable` or collect steps) are included and take precedence.
For example, a tool node can call `https://api.example.com/orders/{{order_id}}` or send `Authorization: Bearer {{api_token}}` with per-call values.
## Value sources & precedence
A value can arrive from several places. At call start the platform uses this precedence, highest first:
1. **Explicit** — values passed with the call, such as API `make-call` `variables`.
2. **Inbound variable-webhook** — enrichment fetched at call start (see [below](#inbound-variable-webhook)).
3. **Current contact and system values** — selected Custom Attributes and values filled by the platform from this call's context.
4. **Remembered caller variable** — the last consented value kept in the configured Shared or Private scope.
5. **Default** — the definition's `default_value`.
A double-brace placeholder with no value becomes an empty string. Unknown legacy single-brace text stays unchanged.
### Explicit values via the API
```bash theme={null}
curl -X POST https://app.famulor.io/api/v1/calls \
-H "Authorization: Bearer fam_..." \
-H "Content-Type: application/json" \
-d '{
"assistant_id": "asst_123",
"to_number": "+493012345678",
"variables": { "customer_name": "Jordan", "appointment_date": "2026-07-10" }
}'
```
Pass one-call tasks in `variables`, including values for Manual variables. Putting the same key in `lead` does not grant access to that contact field. This request does not edit the assistant or contact; retention follows each variable’s Caller memory setting. Values must be a flat object with lowercase snake\_case keys (up to 64 characters). Strings accept up to 2000 characters; numbers and booleans become text. Nested objects, arrays and null values are rejected. Control characters, invisible formatting and role-marker prefixes are removed before use.
After a call starts, use MCP `get_call` with `expected_variables`, or send `POST /api/v1/calls/{id}/verify-inputs` with `{ "expected_variables": { "auftrag": "Book a consultation" } }`. The read-only response reports only the requested keys: `matched`, `missing`, `different`, or `not_available`. A missing snapshot is not a failed or passed test; check again after the call starts. Matching inputs verifies delivery, not the scenario outcome. A capacity-queued MCP call retains its inputs.
Outbound calls also prefill call-only defaults and selected contact values before call-start enrichment; those prefilled values can take precedence over a later webhook. An explicit per-call value has the highest priority.
### Campaign leads → variables
In a [campaign](/campaigns/overview), each lead can include free-form **custom fields**. At dial time, a custom field is mapped onto a variable with the **same key**, so a CSV column becomes a variable:
```csv theme={null}
phone_number,name,company_name,appointment_date
+493012345678,Jordan,Northwind,2026-07-10
+491701234567,Alex,Contoso,2026-07-11
```
Here `company_name` and `appointment_date` populate `{{company_name}}` and `{{appointment_date}}` only after those fields exist as workspace Custom Attributes and are selected for this assistant. That selection creates a definition with `source: "lead"`; arbitrary or deleted lead fields are not exposed. Contact `name` is separate identity data and is available through the built-in `{{customer_name}}` system variable.
## System variables
These keys are always available at call start. They are reserved — you cannot define a custom variable with one of these keys.
| Key | Label | Description | Example |
| ---------------- | -------------- | --------------------------------------------------------------------------------------- | ---------------------- |
| `caller_number` | Caller number | The phone number the call is coming from (inbound) / being placed to (outbound), E.164. | `+493012345678` |
| `called_number` | Called number | The number that was dialed / your number that received the call, E.164. | `+498998765432` |
| `assistant_name` | Assistant name | The name of the assistant handling the call. | `Reception Bot` |
| `direction` | Call direction | `inbound`, `outbound` or `web`. | `inbound` |
| `call_id` | Call ID | Unique identifier of this call. | `c_a1b2c3` |
| `date` | Date | Current date at call start (assistant timezone), `YYYY-MM-DD`. | `2026-07-05` |
| `time` | Time | Current time at call start (assistant timezone), `HH:MM`. | `14:30` |
| `datetime` | Date & time | Current date and time at call start (ISO 8601). | `2026-07-05T14:30:00Z` |
| `weekday` | Weekday | Current weekday at call start. | `Sunday` |
## Inbound variable-webhook
For **inbound** calls you often don't know the caller in advance. Configure a **variable webhook** on the assistant and Famulor calls it at call start to enrich variables — for example, to look up a customer by their caller number. This fires before the call starts; see [Post-call webhooks](/assistants/webhooks) for what Famulor sends after one ends.
### Request
Famulor sends a `POST` with a JSON body:
```json theme={null}
{
"event": "call.variables",
"assistant_id": "asst_123",
"call_id": "c_a1b2c3",
"direction": "inbound",
"from_number": "+493012345678",
"to_number": "+498998765432"
}
```
The raw request body is signed with HMAC-SHA256 using the webhook secret configured for the assistant. The signature is sent in this header:
```text theme={null}
X-Famulor-Signature: sha256=
```
### Response
Return the variables to merge:
```json theme={null}
{
"variables": {
"customer_name": "Jordan",
"open_amount": "128.50"
}
}
```
These values override system variables and defaults, but explicit values supplied for the call take precedence. If the lookup fails, the call continues with the values already available.
### Native automation (alternative)
Instead of a custom webhook, you can create an [**Automation**](/automations/overview) with the **Inject input variables** trigger and bind it to the assistant. Add a **Return variables** action using the same `{ variables: {…} }` response shape. If no matching automation is active, the configured webhook is used.
### Verifying the signature
```js Node.js theme={null}
import crypto from "node:crypto";
// rawBody: the exact bytes received, before JSON.parse
function verify(rawBody, signatureHeader, secret) {
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(signatureHeader);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```
```python Python theme={null}
import hmac, hashlib
# raw_body: the exact bytes received, before json.loads
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)
```
Always compute the HMAC over the **raw** request body bytes, not over a re-serialized object — re-serialization can change whitespace or key order and break the signature. Use a constant-time comparison.
### Example request
```bash theme={null}
curl -X POST https://your-app.example.com/famulor/variables \
-H "Content-Type: application/json" \
-H "X-Famulor-Signature: sha256=6d3a...e1f0" \
-d '{
"event": "call.variables",
"assistant_id": "asst_123",
"call_id": "c_a1b2c3",
"direction": "inbound",
"from_number": "+493012345678",
"to_number": "+498998765432"
}'
```
## API & MCP
* `GET /api/v1/assistants/{id}/variables` — read the assistant's variable definitions; scope `assistants:read`.
* `PATCH /api/v1/assistants/{id}/variables` — replace the variable definitions; scope `assistants:write`.
* MCP tools: `get_assistant_variables`, `set_assistant_variables`.
Full REST reference lives at [docs.famulor.io](https://docs.famulor.io). Use `{{key}}` everywhere you want a per-call value, keep keys `snake_case`, and give every variable a sensible `default_value` so calls degrade gracefully when a source is missing.
# Voice cloning consent
Source: https://docs.famulor.io/assistants/voice-cloning-consent
What consent to get in place before you clone someone's voice for an assistant
A cloned voice is built from real speech recordings of a real person. Before you use one — your own, an employee's, or anyone else's — you need that person's clear consent. This page explains why, and gives you a practical checklist.
This page explains the general legal landscape around voice cloning in the EU. It is not legal advice. Talk to your own counsel about your specific situation, especially before cloning anyone's voice for commercial use.
## Why consent is required
A voice identifies a person almost as reliably as a fingerprint, and the law treats it accordingly:
* **It's personal data.** Under the **GDPR**, a voice recording used to identify someone is **biometric data** — a special category under Article 9 that may not be processed without a clear legal basis, and in practice that basis is the person's **explicit consent**.
* **It's protected by personality rights.** In the EU and most other jurisdictions, a person has the right to decide whether their voice is recorded, published, or imitated. Cloning someone's voice without permission can expose you to injunctions and damages, independent of GDPR.
* **Performers have their own rights.** If the voice belongs to a professional speaker, actor, or voice performer, their recordings are typically also covered by **neighboring/performers' rights** — separate from the personality-rights protection above, and usually running for decades after the recording is made.
* **Copyright doesn't apply to the voice itself.** Copyright protects a specific recording or performance, not the sound of a voice in the abstract — so it's not a substitute for consent, and it doesn't give you permission to clone a voice just because you own a recording of it.
## What valid consent looks like
Consent that will hold up needs to be:
| Requirement | What it means in practice |
| -------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Voluntary** | Given freely, without pressure — an employee shouldn't feel their job depends on saying yes |
| **Informed** | The person understands what their voice will be used for, in what products or channels, and for how long |
| **Specific** | Tied to a defined purpose — consent for an internal IVR prompt doesn't cover a public ad campaign |
| **Documented** | Captured in writing or another durable, retrievable form — a verbal "sure, go ahead" isn't enough if it's ever challenged |
| **Revocable** | The person can withdraw consent at any time, and you stop using the clone when they do |
Extra care applies when the voice belongs to a minor — consent must come from a parent or legal guardian.
## Labelling AI-generated audio
Since August 2026, the **EU AI Act** requires that AI-generated or manipulated audio realistic enough to be mistaken for a real recording of a person — a "deepfake" — is disclosed as artificially generated. In practice, that means telling your customers or audience when they are hearing a cloned voice rather than the person themselves.
Two narrow cases soften this: in evidently artistic, creative, satirical, or fictional work the disclosure only has to exist in a way that doesn't spoil the piece, and the duty doesn't apply where the use is authorised by law to detect, prevent, investigate, or prosecute criminal offences.
## Practical consent checklist
Have the voice owner (or their guardian, for a minor) agree in writing to the specific purpose, product, and duration of use — before you create the clone, not after.
Keep the signed consent somewhere durable and access-controlled. You may need to produce it later.
Use the clone only for what was agreed. A new use case — a new product, a new market, a public campaign — needs its own consent.
Give the person a clear way to withdraw consent, and have a process ready to delete or deactivate the cloned voice when they do.
If the audience could mistake the cloned voice for the real person, disclose that it's AI-generated.
Need a consent form or usage agreement template? [Contact support](/support) — we don't publish sample contracts in these docs, since the right wording depends on your jurisdiction and use case, but our team can point you to a starting template.
## Where cloned voices are used in Famulor
Once you have consent, open the assistant's **Voice** tab, go to the [voice library](/assistants/models-and-voices#voice-library), and select **Clone a voice**. Upload or record a clean sample; the finished voice then appears under **Cloned voices** — private to your workspace, never shared with anyone else — and can be picked like any other library voice.
Cloning your own voice needs the **Clone your own voice** add-on; check your workspace's **Settings → Plan** for availability and how many cloned voices your plan allows.
Need more than your plan includes? Extra cloned-voice slots are purchasable individually, also from **Settings → Plan**. A slot only adds capacity on top of the **Clone your own voice** add-on — buying slots alone, without that add-on, doesn't unlock cloning.
# Post-call webhooks
Source: https://docs.famulor.io/assistants/webhooks
Receive the transcript, duration, input variables, and post-call analysis via webhook after every call.
Configure an **assistant-level webhook URL** on each assistant (**Settings → Automations → Call completed**). After every call, Famulor sends a `call.completed` POST with:
* Transcript
* Duration
* Resolved input variables
* Post-call analysis (and [AI QA scorecard](/assistants/analysis#ai-qa-scorecards) when enabled)
* Failure guidance when an outbound call did not connect
The optional `failure` object explains what happened, whether retrying may help, and what action to take. The same customer-facing guidance is available through REST and MCP call reads.
## Webhook settings
| Setting | Range | Default | Meaning |
| ----------- | --------- | ------- | -------------------------------------- |
| Webhook URL | HTTPS URL | — | Delivery target for this assistant |
| Timeout | 1–30 s | 5 s | Max wait for a response |
| Retry count | 0–5 | 2 | Extra attempts after the first failure |
Use **Test** in the editor to send an example payload to an unsaved or saved URL (respects the timeout slider).
This URL is unsigned and specific to this assistant. Famulor has no workspace-wide webhook subscription — call results are always delivered per assistant.
## Example webhook payload
A `call.completed` delivery looks like this:
```json theme={null}
{
"event": "call.completed",
"timestamp": "2026-08-26T14:32:07.000Z",
"data": {
"call_id": "c1b2c3d4-0000-4000-8000-000000000010",
"tenant_id": "9f86d081-0000-4000-8000-000000000020",
"assistant_id": "1b2c3d4e-0000-4000-8000-000000000030",
"direction": "outbound",
"status": "completed",
"duration_sec": 132,
"transcript": {
"items": [
{ "type": "message", "role": "assistant", "content": ["Hi, this is Alex from Riverside Dental."] },
{ "type": "message", "role": "user", "content": ["Hi, yes, I have a moment."] }
]
},
"collected": { "appointment_time": "2026-09-02T10:00:00Z" },
"variables": { "lead_quality": "high" },
"input_variables": { "customer_name": "Max Mustermann" },
"analysis": {
"summary": "Customer confirmed interest and booked a demo.",
"sentiment": "positive",
"success": true,
"success_reason": "Appointment booked"
},
"qa_scorecard": null
}
}
```
`variables` and `input_variables` follow the same [call variables](/assistants/variables) used elsewhere on the assistant. `analysis` and [`qa_scorecard`](/assistants/analysis#ai-qa-scorecards) are only populated once post-call processing finishes. When an outbound call didn't connect, a `failure` object is added alongside the result — see above.
## API & MCP
Use `PATCH /api/v1/assistants/{id}` or the MCP `update_assistant` tool. Delivery can be off, the assistant webhook URL, or a [bound automation](/automations/overview). See the API schema for the current field contract.
# Audience Call QA
Source: https://docs.famulor.io/audience/call-qa
Use per-contact call quality averages in Audience, segments, History, REST and MCP.
Audience's filter builder narrows your contact list by status, channel, tags, source, custom attributes, and per-contact Call QA score — save any combination as a reusable segment.
Audience represents a contact, while History represents that contact's individual interactions across calls, messaging and email. A contact can therefore have many History rows but only one Audience row.
## Filter builder and saved segments
Select **Filter** above the Audience table to combine conditions in one visual
filter builder. Conditions are ANDed; multiple values inside Status,
Channel, Source, Tags or AMD result are ORed. Available conditions are:
* contact search, display status, campaign and DNC
* channel and Call QA
* contact source and tags
* created-date and call-attempt ranges
* last AMD result
* workspace-defined custom attributes
The list updates while conditions change. Select **Save as segment** to store the
current definition as a dynamic segment. A segment stores the filters, not a
snapshot of contacts, so campaign assignment always resolves the latest matches.
For **DNC**, choose **is** to include only contacts on the block list or
**is not** to exclude them. In REST and MCP filters this is represented as
`dnc: true` and `dnc: false`; omitting `dnc` leaves the list unfiltered.
## Contact tags
Add workspace-specific tags when creating a contact, or open **Manage Contact →
Tags** to edit them later. Enter one tag at a time or paste comma-separated tags.
Tags are normalized to lowercase, deduplicated, and limited to 32 tags with 40
characters each. CSV imports can map a comma- or semicolon-separated column to
**Tags**. CRM Sync can map a CRM label/tag field to the same destination; synced
tags merge with manual tags instead of replacing them.
Use the **Tags** filter to find any contact containing one of the selected tags,
then save the definition as a reusable segment. API clients can create an
unassigned tagged contact with `POST /leads`; MCP clients can use
`create_audience_contact`. To attach an existing contact's phone, email, or
channel identity to another contact, use `POST /leads/{id}/merge` or MCP
`merge_audience_contacts` — this is explicit and never happens on PATCH.
## Call QA average
The **Call QA** value is the average QA score for the selected contact and period:
* 7, 30 or 90 days, or all time
* default: 90 days
* every call counts once
* calls without a score are excluded
* messaging and email remain in the shared timeline but are not scored in this phase
The value measures assistant performance in calls. It is not a lead-quality score. The number of scored calls is shown next to the average; the contact drawer additionally shows pass rate and the latest score.
## Dynamic QA segments
Enable **QA filter** in Audience, select a period and optionally set a minimum average, maximum average or minimum number of scored calls. Saving the current filters creates a dynamic segment.
```json theme={null}
{
"qa": {
"window": 90,
"average_score_min": 80,
"min_scored_calls": 3
}
}
```
Contacts without scored calls do not match a QA segment. When `min_scored_calls` is omitted, at least one scored call is required. Segment membership is recalculated whenever the segment is resolved, including campaign assignment.
Creating or changing a QA segment requires the **[AI QA scorecards](/assistants/analysis#ai-qa-scorecards)** plan feature. Existing saved segments remain readable and resolvable after a downgrade.
## Dynamic channel segments
Use the **Channel** filter to select contacts that have linked activity or a channel profile. Supported values are calls, SMS, email, WhatsApp, Telegram, Slack, Messenger, Microsoft Teams, Discord, Google Chat, X, Freshdesk, Gmail, Outlook, Zendesk, ServiceNow, Intercom, Zoho Mail, AgentMail, Instagram, and Zulip.
```json theme={null}
{
"channels": ["whatsapp", "messenger"]
}
```
Multiple channel values are ORed: the example matches contacts with WhatsApp **or** Messenger. Channel criteria are ANDed with search, status, campaign, DNC, source, tags, date, attempts, AMD, attributes and Call QA. Membership is recalculated whenever the segment is opened or assigned to a [campaign](/campaigns/overview).
## Unified contact history
Use **View all history** in the contact drawer to open History for that contact. Calls, messaging conversations, and email threads are included. Email appears once per thread rather than once per message.
API clients can use `GET /api/v1/leads`, `GET /api/v1/history?lead_id=...`, and the segment endpoints. MCP clients can use `list_audience_contacts`, `list_history` with `lead_id`, and the segment tools.
# Contacts
Source: https://docs.famulor.io/audience/contacts
Create, edit, merge, and delete the people and businesses in your Audience
A contact is one record for a person or business — shared across every call, message, email thread, and campaign they're part of. Audience keeps a single contact list for the whole workspace; campaigns pull leads from it instead of each keeping a private list.
## Creating a contact
Select **New Lead** in Audience to open the **New contact** form. A name is optional; a phone number or an email address is required — either one on its own is enough. Both must be unique in the workspace, so if a value already belongs to another contact, the form flags the match and offers to open that contact or add the missing detail to it instead of creating a duplicate.
Contacts also arrive without anyone filling in that form: from a [CSV import](/audience/importing-contacts), the first time someone calls or messages in on one of your numbers, when a lead is added to a campaign, and through the REST API or MCP.
## Editing a contact
Open a contact to see three tabs:
* **Overview** — segments, last contacted, Call QA average (where [AI QA scorecards](/assistants/analysis#ai-qa-scorecards) are enabled), personal details, custom attributes, and any linked channel profiles.
* **Memory** — consent-aware [customer memory](/assistants/memory) and verified identities gathered across channels.
* **Timeline** — every call, message, and email for this contact, with a link into [History](/monitoring/history) for the full record.
The action bar at the bottom of the drawer starts a call with any active assistant, opens an email to the contact, and — under **More actions** — offers **Manage** and **Delete**. **Manage Contact** edits the record across four tabs: **Info** (name, phone, email, photo), **Tags**, **Attributes**, and **Channels**.
In **Channels**, select **Add channel** to link a verified messaging identity to the existing contact. Microsoft Teams identities are tied to one active Teams connection: the only active connection is selected automatically, while workspaces with several connections must choose one. If the same channel identity is already linked to another contact on that connection, the save is rejected and the contacts remain separate until you explicitly merge them.
Tagging, filtering, and saved segments are covered in [Audience Call QA](/audience/call-qa) — this page focuses on the contact record itself.
## Custom attributes
Define workspace-wide fields under **Settings → Workspace → Custom Attributes**: a name, a type, and whether it's required. The types are **Text**, **Number**, **Boolean** (a yes/no field), **Enum** (a list of choices you define), and **Date**. The attribute's key is generated from the name — "Maiden Name" becomes `maiden_name` — and the type is fixed once the attribute exists.
A workspace can define up to 50 attributes, and an Enum attribute can offer up to 50 choices. Values live in the **Attributes** tab of a contact, or are filled in automatically during CSV import.
An assistant opts in to the attributes it needs: in the assistant's **Variables** panel, tick the attribute under **Lead attributes** and its value is available as `{{key}}` on every call with that contact. See [Custom variables](/assistants/variables).
## Contact status
Every contact carries one status, driven by its most recent campaign activity:
| Status | Meaning |
| ----------------- | ------------------------------------------------------------------------------------------ |
| Created | Not yet called |
| Processing | A call is in progress right now |
| Rescheduled | Waiting for its next retry |
| Max retries | Retry budget used up without a result |
| Completed | Reached, or the campaign's goal was achieved |
| DNC (Blacklisted) | On the [do-not-call list](/campaigns/dialer-and-compliance#do-not-call-dnc) — never dialed |
Filter Audience by status to find contacts in any of these states. The same six states drive the drag-and-drop board inside a campaign, where the columns carry campaign-facing names — see [Monitoring a running campaign](/campaigns/overview#monitoring-a-running-campaign).
## Merging duplicate contacts
Phone numbers and email addresses are unique per workspace, so Famulor never lets a second record claim an identity that already exists:
* **On create** — adding a single contact whose phone or email already belongs to someone else merges the new tags and fills in any missing identity fields on that contact, instead of creating a second record. This applies to the **New contact** form, `POST /api/v1/leads`, and MCP `create_audience_contact`.
* **On edit** — if you change a contact's phone or email to a value already used elsewhere, the Info tab flags the collision and offers **Merge into this contact**. Merging moves phone, email, channel identities, calls, and conversations onto the contact you keep and removes the other record.
* **On import** — bulk imports never merge. A CSV row or campaign lead whose phone or email is already taken is rejected rather than folded into the existing contact, so deduplicate against Audience before a large import. See [Importing contacts](/audience/importing-contacts).
Merging two existing contacts is always explicit. A colliding phone or email on a plain update is rejected, not silently merged — you have to confirm the merge yourself.
The same operation is available as `POST /api/v1/leads/{id}/merge` or the MCP tool `merge_audience_contacts`.
## Deleting a contact
Delete a contact from **More actions** in its drawer. This removes the contact record permanently and cannot be undone.
Taking a lead out of a [campaign](/campaigns/overview) is a different, non-destructive action: the lead leaves that campaign's queue, and the contact — with its calls, conversations, and history — stays in Audience.
## API & MCP
```bash theme={null}
GET /api/v1/leads # list contacts, with status/channel/tag/date filters
POST /api/v1/leads # create a contact (or merge into a matching one)
GET /api/v1/leads/{id}/channels
PUT /api/v1/leads/{id}/channels # replace channel profiles; Teams uses connection_name
POST /api/v1/leads/{id}/merge
```
Active Microsoft Teams connections must have unique names within the workspace, because `connection_name` is the public selector used by the API and MCP. Reconnected copies of the same Microsoft identity are normalized to one current connection name.
MCP clients can use `list_audience_contacts`, `create_audience_contact`, `list_audience_contact_channels`, `replace_audience_contact_channels`, and `merge_audience_contacts` for the workspace-wide contact list. `get_lead`, `update_lead`, and `delete_lead` work on a **campaign** lead rather than the Audience record — and `delete_lead` only takes the lead out of its campaign; the contact stays in Audience.
# Importing contacts
Source: https://docs.famulor.io/audience/importing-contacts
Bring contacts into Audience from a CSV file, with column mapping and validation
CSV import is the fastest way to add many contacts at once — whether you're starting a fresh list or topping up Audience from a spreadsheet export.
## Preparing your file
* **CSV only** (not Excel), UTF-8 encoded, up to 12MB.
* Comma- or semicolon-separated — Famulor detects which from the first line, so European spreadsheet exports work as-is.
* A header row is strongly recommended: Famulor reads it to pre-match obvious columns. A file without one still imports; the columns are just labeled Column 1, Column 2, and so on.
* Every row needs a phone number. Everything else — name, email, tags, custom fields — is optional.
```csv theme={null}
phone,name,email,tags,company
+491701234567,Ada Lovelace,ada@example.com,vip;renewal,TechStart Solutions
+14155551234,Grace Hopper,grace@example.com,,Acme Corp
```
## Import steps
Select **Import** in Audience. The wizard has three steps.
Drag in your CSV or choose it from disk. You'll be asked to certify that these contacts consented to being contacted and aren't from a purchased list — this is your responsibility, not something Famulor validates for you.
Map each column to a target: a contact field (**Phone**, **Name**, **Email**, **Tags**), an assistant variable (when importing directly into a campaign with an assistant assigned), a workspace **custom attribute**, or a free-form custom key. Obvious matches — a column literally called "phone" or "email" — are pre-selected; review and adjust the rest, and set anything you don't need to **Ignore this column**.
This step also carries two settings for the whole batch. **Default country for phone numbers** is appended to any number that doesn't already include a country code (`01701234567` → `+491701234567`), so you don't have to split your file by country first. **Tags** adds the same tags to every contact in the batch.
Review the first five mapped contacts, check the **Ready to import** and **Skipped (invalid phone)** counts, and confirm.
## Where imported contacts land
Import from **Audience** creates unassigned contacts, available to every campaign and segment in the workspace. The same **Import** button also sits on a campaign's own page — used there, it adds the contacts straight to that campaign's queue instead of leaving them unassigned.
To add already-existing Audience contacts to a campaign instead of re-importing them, use **Assign leads** on the campaign — pick a saved segment or hand-pick contacts. See [Setting up a campaign](/campaigns/overview#setting-up-a-campaign).
## Column mapping reference
| Target | Where values come from |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| Phone, Name, Email, Tags | Built-in contact fields. A **Tags** column may hold several tags separated by commas or semicolons |
| Assistant variable | Offered only when importing into a campaign with an assistant assigned |
| Custom attribute | Workspace-defined fields under **Settings → Workspace → Custom Attributes** |
| Custom key | Free-form: lowercase letters, digits, and underscores, starting with a letter. `phone`, `name`, `email`, and `tags` are reserved |
## Keeping your data clean
* Prefer E.164 phone format (`+491701234567`) over local formats (`0170 123 4567`, `(030) 123-4567`) — it removes any ambiguity about the country.
* Save the file as UTF-8 CSV. If you're exporting from Excel, convert formulas to values and avoid merged cells before saving.
* **Deduplicate before you import.** Phone numbers and email addresses are unique per workspace, and an import doesn't merge into existing records the way the single-contact form does — a row whose phone or email already belongs to a contact fails instead. Remove those rows from the file first, or update those contacts individually in Audience.
* Give each import batch a shared tag (e.g. `import-2026-08`) in the Match Columns step so you can find that batch again in Audience afterward.
## Troubleshooting
| Symptom | Fix |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Upload is rejected outright | File must be `.csv`, UTF-8 encoded, and 12MB or smaller — Excel (`.xlsx`) isn't supported; export or save as CSV first |
| No contacts imported | Make sure a column is mapped to **Phone** — a row with no valid phone number is always skipped |
| Fewer contacts than rows in the file | Check the **Skipped (invalid phone)** count on the preview step; those rows had a phone number that couldn't be parsed |
| The import stops with a duplicate-identity error | A row's phone or email already belongs to another contact in this workspace. Remove the duplicate rows and import again — contacts already created before the failure stay |
| Wrong country code was added | Only numbers without a country code get the default country appended — set the correct default before confirming, or fix those numbers to include `+` in the file |
| A custom key is rejected | Keys must be lowercase letters, digits, and underscores, starting with a letter. `phone`, `name`, `email`, and `tags` are reserved; rename the column or pick an existing custom attribute instead |
See also [Contacts](/audience/contacts) for editing and merging records after import, and [Campaigns overview](/campaigns/overview) for assigning contacts to outreach.
# App Catalog
Source: https://docs.famulor.io/automations/app-catalog
Every platform you can pick a trigger or an action from in the Automation builder
The **App Catalog** is the two-pane picker inside the Automation builder: choose a platform on the left, and its **triggers** (what starts a run) and **actions** (what a step does) appear on the right. Famulor's own built-ins sit alongside every app your workspace has connected.
Anything that reaches an outside system needs a saved connection first. Store one under **Automations → Connections** — a CRM key, an SMTP relay, an MCP endpoint — and every automation node in the workspace can use it. **Import from Tools** brings across an MCP server you already configured in [Agent Tools](/assistants/agent-tools), reusing the same credentials or sign-in.
Connections are not the same thing as [Agent Connectors](/assistants/agent-tools#agent-connectors), the separate app store that attaches an app to an assistant as a callable tool. To let an assistant reach a catalog app while a conversation is still running, make the automation itself [callable from the conversation](/automations/overview#calling-an-automation-from-a-conversation).
## Famulor built-ins
Every workspace starts with these — no connection needed.
| Area | What it covers |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Triggers | Start a run when a call ends or comes in, when a call needs its input variables, when a conversation opens or closes, on a new message or email, on a booking created, cancelled, or rescheduled, on a new Audience contact, on a manual run, or on an incoming webhook. |
| Calls | Start an outbound call with an assistant. |
| Contacts | Create or update an Audience lead, look one up by phone, list recent leads, add tags or attributes, and add or remove someone from the block list. |
| Messaging | Send an SMS, send an email through the workspace email channel, or reply on whichever messaging channel the trigger fired from. |
| Knowledge base | Add, read, or delete a knowledge document. |
| Logic & variables | Branch with Condition, Filter, Switch, or a random split, loop over a list, run custom code, set variables, and annotate the run log. |
| Ending a run | Stop, Return variables, or Respond to webhook. |
See the [Automation node reference](/automations/nodes) for every trigger and step with its fields and behavior.
## Communication
Each channel sends on an open conversation; Slack, Discord, and Teams can also post through an Incoming Webhook URL without one.
| App | What you can do |
| ----------------- | ----------------------------------------------------------------------------- |
| WhatsApp Business | Send on an open conversation, or send an approved template to open a new one. |
| Slack | Send a message on an open conversation, or post to a channel. |
| Discord | Send a message on an open conversation, or post to a channel. |
| Microsoft Teams | Send a message on an open conversation, or post via webhook. |
| Messenger | Send a Facebook Messenger message on an open conversation. |
| Google Chat | Send a Google Chat message on an open conversation. |
| Telegram | Send a Telegram message on an open conversation. |
| X | Send an X direct message on an open conversation. |
## CRM & sales
| CRM | What you can do |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HubSpot | Get, search, create, or update contacts, create a deal, and attach a note. |
| Salesforce | Run a SOQL query, and get, create, or update any object record. |
| Pipedrive | List, search, get, create, or update a person, create a deal, and add a note. |
| HighLevel | List, get, create, or update contacts, create an opportunity, log a note, and read calendars and free slots to book, reschedule, or cancel appointments. |
| Close.io | Create or update a lead, attach a contact, create an opportunity, post a note, and search leads by query. |
| Zoho CRM | List, search, get, create, or update records on any CRM module. |
| Attio | List, get, create, or update records on any object. |
| Keap | List, get, create, or update contacts, create an opportunity, and log a note. |
| Twenty CRM | List, get, create, or update records — hosted or self-hosted. |
Each CRM above, plus Airtable, can also start a run from that provider's own webhook event; the trigger shows its inbound URL and secret once the automation is saved. To keep your whole Audience list continuously aligned with one of these CRMs, instead of writing individual records from a step, see [Supported CRMs](/automations/crm-sync#supported-crms).
## Data & backend
| App | What you can do |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Airtable | Find, search, list, get, find-or-create, create (one record or up to ten), update, or delete records — base, table, field, and view pickers load from your own schema. |
| Supabase | Call the official Supabase MCP for SQL, schema, Edge Functions, and logs. |
| Neon | Call the official Neon MCP for projects, branches, SQL, and schema. |
| SMTP | Send email through your own SMTP relay instead of the platform mail server. |
| HTTP / Webhook | Call any HTTPS endpoint from a step, or start a run from an inbound POST, then answer it synchronously with Respond to webhook. |
| MCP | Call a tool on any connected MCP server — ready-made connections cover Notion, Stripe, GitHub, Linear, and Slack, plus any custom endpoint you host. |
## Commerce, marketing & productivity
| App | What you can do |
| --------- | ----------------------------------------------------------------------------- |
| Shopify | Call the official Shopify Storefront MCP for catalog, carts, and policies. |
| Brevo | Call the official Brevo MCP for contacts, campaigns, and transactional email. |
| Atlassian | Call the official Atlassian MCP for Jira, Confluence, and Bitbucket. |
## AI & time
| App | What you can do |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Milian AI | Generate free-form text, or extract structured fields from any text or call transcript. Both bill workspace credits. |
| Time | Delay a run for a number of seconds or until an absolute date and time, read the current time, convert between timezones, format a date for a later step, and (coming soon) start a run on a recurring schedule. |
## Browse apps (Beta)
Beyond the catalog above, **Browse apps (Beta)** — under **Connections → Add Connection** — connects hundreds more apps over OAuth. Each connected app brings its own triggers and actions into the builder right away. Requires workspace **Beta Features**, turned on under **Settings → Workspace**.
## Next steps
Every trigger and step, with its fields and behavior
Concepts, billing, and worked example automations
Keep Audience and a connected CRM aligned on a schedule
# CRM sync
Source: https://docs.famulor.io/automations/crm-sync
Keep Audience contacts aligned with your CRM and write call outcomes back through automations.
CRM sync (Revenue Autopilot) is a beta feature. A workspace admin must enable
**Beta features**, and the workspace needs the **Revenue Autopilot** add-on
(or Include free on the plan) plus CRM sync capacity limits.
CRM sync keeps Audience and a connected CRM aligned on a recurring schedule.
Agents, campaigns, segments, and automations can then use the current contact
attributes without CSV uploads.
| Direction | Behavior |
| -------------- | ----------------------------------------------------------------------------------------- |
| CRM → Audience | Imports contacts, leads, deals, and mapped attributes into Audience. |
| Audience → CRM | Updates linked CRM records from Audience. Optionally creates missing CRM records. |
| Both ways | Imports first, then exports, on the same schedule. Unchanged values are not written back. |
Creating missing records depends on the object type: supported for HubSpot contacts, Salesforce contacts/leads, Pipedrive persons, Close contacts and leads, and Attio/Twenty people; HighLevel and Keap support it across all their object types.
Call outcomes can still be written through **automation CRM action nodes** after a call or qualification step. That path is independent of Audience CRM Sync.
Exporting uses one-to-one field mappings. Combined values such as `{{firstName}} {{lastName}}` can be imported, but they cannot be reversed for export.
## Supported CRMs
CRM Sync has a native adapter for each of these providers, so all three directions in the table above are available once you add an API connection for it:
* HubSpot
* HighLevel
* Salesforce
* Pipedrive
* Close.io
* Zoho CRM
* Attio
* Keap
* Twenty Cloud and self-hosted Twenty
Twenty Cloud uses `https://api.twenty.com`. For a self-hosted instance, enter a
public HTTPS URL that the platform can reach over the internet.
A CRM that isn't on this list has no native Audience sync, but automations can still reach it — call its API with an HTTP Request action, connect it as a custom MCP endpoint, or search for it under Browse apps (Beta). See the [App Catalog](/automations/app-catalog) for the full directory of built-in and connected apps.
## Connect HighLevel
Open **Automations → Connections → HighLevel** and choose **Authorize HighLevel**. Select the sub-account you want to use and approve the requested permissions. The same connection can be used by CRM Sync and HighLevel automation actions, including supported calendar and appointment actions.
## Create a sync
1. Open **Automations → Connections** and add an API connection for the CRM.
Compatible connections carry the **CRM Sync** tag in **Add Connection**.
2. Open **Audience → CRM Sync**.
3. Select the connection and CRM object or source.
4. Map CRM fields to Name, Phone, Email, Tags, a custom Audience attribute, or a supported channel identity. Mapped email values also create the contact's Email channel profile automatically.
Assign more than one source field to the same destination to combine the values.
5. Review up to three read-only CRM samples after the mapping.
6. Choose the interval and start the sync.
The mapper suggests standard fields and matches existing custom attributes by name. A channel mapping alone never creates a new contact; Phone or Email remains the match key.
Choose **Custom value** for a destination to combine CRM-field chips and
text in the exact order you need. For example, `Salutation + First name + Last
name` can build `name`; `Calling code + Phone number` can build `phone`. At
least `phone` or `email` is required so the first CRM record can be matched to
an Audience contact safely.
For national phone numbers, choose a **Default phone country** such as Germany.
The preview and the real run use the same country-aware parser and store the
result in E.164 form (`+49152…`). International numbers that already start with
`+` or `00` ignore the fallback. If the CRM exposes a separate ISO country
(`DE`) or calling-code (`+49`) field, map it before the phone-number field in
the same `phone` composition. Invalid phone and email combinations are marked
in the read-only preview before anything is saved.
The API and MCP keep the simple mapping shape. A single source remains a bare
field key. Combined values use safe `{{field}}` tokens with optional literal
text; no code is evaluated:
```json theme={null}
{
"{{salutation}} {{firstName}} {{lastName}}": "name",
"{{phones.primaryPhoneCallingCode}}{{phones.primaryPhoneNumber}}": "phone",
"email": "email"
}
```
Map a CRM label or tag field to `tags` to merge normalized, lowercase tags into
the contact. Existing manual tags remain intact, and imported tags immediately
appear in the Audience tag filter.
The first run imports the selected source. Later runs skip unchanged records and resume safely after temporary interruptions.
## Edit a sync
Use the pencil action on a sync card to update its name, object, source,
interval, phone country, or field mapping, then review the same mapped-data
preview used when creating a sync. **Save only** keeps the existing schedule.
**Save & sync** saves the same changes and immediately starts a manual run.
Changing the object, source, or mapping causes the next run to reapply the new mapping to existing CRM records.
## Identity and conflict behavior
The stable CRM record ID keeps each imported record linked to the correct
Audience contact. Email and phone are used only to find a safe initial match.
Ambiguous matches are reported as conflicts instead of merging unrelated people.
CRM sync never deletes an Audience contact. Records no longer present in the
selected CRM source can be marked inactive for that sync. Local compliance data,
including the block list and consent decisions, is never cleared by CRM data.
## Write outcomes back
Use the [CRM action nodes](/automations/nodes#external-connections) in an automation after a call or qualification step.
Each supported CRM includes record search/get, create, and update actions where
the provider API supports them. Use template values such as `{{data.call_id}}`
and `{{data.from_number}}` from the trigger, or output from an earlier step
(`{{steps.step1.output}}`).
For example, an automation on the **On Call Completed** trigger can read the
call's [analysis](/assistants/analysis) — `{{data.analysis.sentiment}}`,
`{{data.analysis.success}}`, `{{data.analysis.success_reason}}`, and any
custom field the assistant extracts (`{{data.analysis.data.}}`) —
then use a CRM update action to log the outcome on the linked record, or
branch with **Condition** on `{{data.analysis.success}}` to route only
qualified calls into a follow-up sequence.
CRM webhook trigger nodes can start an automation from provider events. Choose
the connection and event in the trigger settings. If a webhook URL or secret is
required, both are shown directly in the trigger.
## Troubleshooting
Start the flow again from **Automations → Connections → HighLevel → Authorize HighLevel** and approve every requested permission. If the sign-in stalls or lands on the wrong account, a stale browser session is the usual cause — sign out of HighLevel or use a fresh private window, then authorize again.
**Authorize HighLevel** connects one sub-account at a time. Reconnect and pick the correct one; a workspace can hold more than one HighLevel connection if you manage several sub-accounts.
At least `phone` or `email` must be mapped in a valid format — check the read-only preview before saving, and add a **Default phone country** if the CRM stores numbers in national format.
A renamed or restructured CRM field doesn't remap itself. Open the sync's pencil action, redo the mapping, and expect the next run to reapply it to existing records.
## Public API and MCP
The same operations are available through:
* `GET|POST /api/v1/crm-syncs`
* `POST /api/v1/crm-syncs/discover`
* `GET|PATCH|DELETE /api/v1/crm-syncs/{id}`
* `GET|POST /api/v1/crm-syncs/{id}/runs`
* MCP tools for listing, creating, updating, deleting, and running CRM syncs
API keys need the corresponding `automations:read` or `automations:write`
scope. Secrets and provider tokens are never returned.
# Automation node reference
Source: https://docs.famulor.io/automations/nodes
Every trigger and step in the Automation builder, with its fields and behavior
This is the field-level reference for the Automation builder — every trigger, every step, and how data moves between them. For what Automations are for, how runs are billed, and worked examples, start with [Automations overview](/automations/overview).
## Automations list tabs
The `/automations` list page has three tabs:
| Tab | Shows |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Automations** | Every workflow in the workspace — connected app icons, name (with its trigger, and the bound assistant if the trigger has one), tags, run count, when it last fired, and status. Search, filter by tag, and activate/pause/delete from the row menu. |
| **Runs** | Every run across every automation — which automation, trigger, status, credits charged, when, and the error if it failed. The same list, scoped to one automation, also lives in that automation's own **Runs** tab in the editor. |
| **Connections** | Saved, reusable credentials for CRMs, SMTP, and MCP servers. Each row shows a provider icon, a kind badge (API or MCP), and a status pill (ok / pending / error) — test or edit one without touching the automations that use it. |
## Triggers
Every trigger starts from a specific event. Assistant-bound triggers (**On Call Completed**, **On Inbound Call**, **Inject input variables**) require picking a specific assistant. Booking, conversation, and email triggers take an optional **Assistant filter** instead; conversation triggers can also be narrowed to one messaging connection or platform, and booking triggers to a single booking page.
| Trigger | Fires when |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **On Call Completed** | A voice call ends and its post-call analysis is ready. |
| **On Inbound Call** | An inbound call starts ringing, before it's answered or analyzed. |
| **Inject input variables** | A call from the selected assistant is starting — this replaces that assistant's variable webhook for the duration this automation is Live. Pair it with **Return variables**. |
| **Conversation started** | A new messaging conversation opens, on any channel. |
| **Conversation ended** | A messaging conversation closes or times out. |
| **Message received** | Every inbound message on a channel, not just the first one — optionally filter by platform. |
| **Email received** | An inbound email arrives on a workspace address. |
| **Booking created / cancelled / rescheduled** | A booking-page event happens. |
| **Contact created** | A new Audience contact is added. Choose which **sources** count — created manually (on by default), CSV/file import, API, CRM sync — so a bulk import can't fire thousands of runs by accident. |
| **Manual** | Runs only when you click **Run now**, call the API, or ask Milian. |
| **Schedule** | Cron-based, on a timezone (coming soon — selectable today for drafts). |
A generic or CRM webhook trigger gets its own inbound URL and secret, shown directly in the trigger's settings once the automation is saved. HighLevel and connected apps deliver events through a shared, pre-authenticated endpoint instead — set up once for the workspace, not per automation:
| Trigger | Fires when |
| --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Incoming Webhook** | Something POSTs JSON to this automation's inbound URL, with the automation's secret in an `X-Automation-Secret` header. |
| **Airtable / HubSpot / Salesforce / Close.io / Pipedrive / Zoho CRM / Attio / Keap / Twenty CRM webhook** | The connected CRM POSTs an event to this trigger's own inbound URL — same mechanics as Incoming Webhook, just filed under that provider in the catalog. |
| **HighLevel webhook** | HighLevel sends a signed CRM or appointment event from its Marketplace app. One **Marketplace webhook URL** is reused across every HighLevel automation; you scope each automation by picking a **HighLevel connection** and one **HighLevel event**. |
| **App event (Beta)** | A connected app delivers a signed event — a new commit, an inbox message, and so on. Pick the app and event from the catalog. Requires workspace **Beta Features**. |
## Steps
### Logic & flow control
These don't talk to anything outside the automation — they shape which path a run takes, or pause it.
| Step | What it does | Key fields | Example |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------ |
| **Condition** | Branches true or false on a value from the payload. | Payload path, operator (equals / not equals / contains / exists), value | `data.analysis.success` equals `true` → branch to a follow-up text |
| **Filter** | Continues only if the condition matches; otherwise the run ends here, successfully — not as a failure. | Same as Condition | Only continue when `data.status` equals `open` |
| **Switch** | Matches a value against a list of cases — more than two outcomes. | Payload path, cases (JSON), default | Route `data.pipeline_stage` to a different step per stage |
| **Random Outcome** | Picks a random branch from a list — handy for A/B testing a message. | Outcomes (comma-separated) | Split traffic between `variant_a` and `variant_b` |
| **Loop on Items** | Repeats the connected steps once per item in a list. Wire the steps that should repeat off its **Loop** handle, and whatever runs after the loop off **Done**. | Items — a path to an array, e.g. `{{steps.step1.records}}` | Loop over `{{steps.list_records.records}}` and text each one |
| **Delay For** | Pauses the run for a fixed number of seconds. | Seconds | Wait 300 seconds before following up |
| **Delay Until** | Pauses until an absolute date and time. | Until (ISO datetime) | Wait until the day before a booking |
| **Set variable** | Writes a value into the run so later steps can reference it. | Path, value | Store `{{last.text}}` at `vars.summary` |
| **Run Code** | Runs a small restricted JavaScript snippet and returns its value — no imports, no file or process access. | Code (must `return` a value) | Uppercase a phone number before sending it onward |
| **Note** | Writes a message into the run log; changes nothing. | Message | Log `Call from {{data.from_number}}` for later debugging |
Loop on Items processes at most 100 items per loop, and loops can nest up to 5 levels deep.
### Ending a run
A run also ends cleanly whenever a step has no outgoing connection. These three end it explicitly, and two of them hand back a specific answer.
| Step | What it does | Key fields | Example |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------- |
| **Stop** | Ends the run successfully, right here. | Reason (optional, logged) | Bail out early once a case is already handled |
| **Return variables** | Hands variables back to the call at start time — pairs with the **Inject input variables** trigger. Ends the run. | Variables (key/value map) | Return `customer_name` and `tier` before the call begins |
| **Respond to webhook** | Answers the caller of an **Incoming Webhook** trigger with a status and body — the only way that caller gets a real response instead of a generic acknowledgement. Ends the run. | Mode (JSON object / raw text / forward last step), status code, body | Return `{ "ok": true, "id": "{{last.id}}" }` |
When an assistant calls this automation mid-conversation, every path must end at **Respond to webhook**, with no Delay or Loop step first.
### Time
| Step | What it does | Key fields | Example |
| -------------------------------- | ---------------------------------------------------- | -------------------------- | ---------------------------------------------- |
| **Get Current Date and Time** | Reads the current time in a timezone. | Timezone | Stamp a note with the local call time |
| **Convert Timezone** | Converts an instant into another timezone's display. | Datetime, target timezone | Show a UTC booking time in the customer's zone |
| **Convert Date and Time Format** | Formats a datetime as date-only, time-only, or ISO. | Datetime, timezone, format | Format a booking time for a text message |
### AI
Grouped under **Milian AI** in the catalog. Both use workspace credits based on token usage at your workspace's rates. The charged amount appears on the run and in the step's Test panel.
| Step | What it does | Key fields | Example |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | --------------------------------------------------- |
| **Custom Prompt** | Runs a free-form prompt against a transcript, message, or any prior step's output, and returns text. | Prompt, optional system prompt | Summarize `{{data.transcript}}` into two sentences |
| **Extract Fields** | Pulls named, typed fields out of a block of text. Each field is a row in the panel: name, type (text / email / number / boolean / enum), and whether it's required. | Input data, fields | Extract `email` and `budget` from a chat transcript |
### Messaging
Send on an already-open conversation, or start a fresh WhatsApp conversation with an approved template.
| Step | What it does | Key fields | Example |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | -------------------------------------------------------------------- |
| **Send Channel Message** | Replies with text on an open conversation, on whichever platform it's on. | Channel connection, conversation | Reply on whichever channel the trigger fired from |
| **WhatsApp Send Message · Send Telegram · Send X (Twitter) · Send Teams Message · Send Slack Message · Send Discord Message · Send Messenger Message · Send Google Chat Message** | Same as Send Channel Message, pinned to one platform. Slack and Discord can also post straight to a **channel** instead of replying to a conversation. | Channel connection, conversation (or channel, for Slack/Discord) | Post an alert to a Slack channel when a call needs a human |
| **Send WhatsApp Template** | Sends an approved WhatsApp business template to a phone number — the only send here that can open a brand-new conversation outside the 24-hour window. | WhatsApp sender, template, recipient, variable mapping | Text a booking-confirmation template right after **Booking created** |
| **Send SMS** | Sends a text from a workspace number that has SMS enabled. | From number, to, message | Text a missed-call follow-up to `{{data.from_number}}` |
| **Send Email** | Sends from the platform mail server or a verified assistant address. | Sender, to, subject, body | Email the transcript to a support inbox |
| **Send Email (SMTP)** | Sends through your own saved SMTP relay instead of the platform mail server. | SMTP connection, to, subject, body | Send a receipt through your company's own mail server |
### Contacts, calls & compliance
Suppression actions are idempotent — re-adding or re-removing the same identity never fails a run.
| Step | What it does | Key fields | Example |
| ------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------ |
| **Create or Update Contact** | Upserts an Audience lead by phone and/or email. | Phone, email, name, attributes | Save a caller as a lead right after the call ends |
| **Get Contact by Phone Number** | Looks up a lead by phone. | Phone | Check whether `{{data.from_number}}` is already a known lead |
| **Get All Contacts** | Lists recent leads (max 100). | Limit | Pull the newest leads for a digest email |
| **Add Tags to Contact** | Appends tags to a lead. | Contact ID, tags | Tag a lead `hot` after a qualifying call |
| **Add Attributes to Contact** | Merges custom attribute values onto a lead. | Contact ID, attributes | Save a deal size onto the matched lead |
| **Add to blocklist** | Suppresses a phone or email so campaigns and outbound messages skip it. | Phone, email, channel (optional — auto-selects voice or email), reason | Suppress a number the moment someone says "stop" |
| **Remove from blocklist** | Restores a previously suppressed phone or email. | Phone, email | Un-suppress after a fresh opt-in |
| **Call Phone Number** | Starts an outbound call with a chosen assistant. | Assistant, to (E.164), optional Variables | Call a lead back automatically after a missed inbound call |
**Call Phone Number** also accepts optional **Variables** as a flat JSON object, for example `{ "auftrag": "{{data.task}}" }`. Values may be text (up to 2000 characters), numbers or booleans. You can also use an entire mapping from a previous step, such as `{{data.inputs}}`. These are inputs for this call and do not edit the assistant or contact. Invalid or oversized resolved values fail the step before dialing. Check the resulting call’s expected inputs and actual outcome separately; creating a call is not proof that the task succeeded.
### Knowledge
| Step | What it does | Key fields | Example |
| --------------------------- | ----------------------------------------- | ------------------------------ | ------------------------------------------------------ |
| **Add Knowledge Source** | Adds a text document to a knowledge base. | Knowledge base, title, content | Publish a fetched policy update straight into the KB |
| **Get Knowledge Source** | Loads a document's metadata. | Knowledge base, document | Check whether a source already exists before adding it |
| **Delete Knowledge Source** | Removes a document. | Knowledge base, document | Retire an outdated FAQ document nightly |
### HTTP & webhooks
Neither of these needs a saved connection — paste a URL and go.
| Step | What it does | Key fields | Example |
| ----------------------------- | ------------------------------------------------------------------------ | --------------------------- | -------------------------------------------------------- |
| **HTTP Request** | Calls any HTTPS endpoint with the trigger payload or a custom JSON body. | URL, method, headers, body | POST the call summary to an internal ops endpoint |
| **Slack (Webhook)** | Posts to a Slack channel via an Incoming Webhook URL. | Webhook URL, message | Drop a one-line alert in an ops channel when a run fails |
| **Discord (Webhook)** | Posts to a Discord channel via a webhook URL. | Webhook URL, message | Post a heads-up for every new booking |
| **Microsoft Teams (Webhook)** | Posts text to a Teams Incoming Webhook. | Webhook URL, title, message | Notify a Teams channel when a high-value lead comes in |
### External connections
CRM, MCP, and connected-app steps all read or write an external system through a saved credential — add one under **Automations → Connections** before using any of them. Each shows up in the catalog as **Provider · Action** (for example **Airtable · Create record**).
**CRM providers.** See [CRM sync](/automations/crm-sync) for the recurring-sync setup and the HighLevel authorize flow — these action nodes write one record at a time, independent of any sync schedule.
| Provider | What you can do |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Airtable** | List, find, search, find-or-create, get, create (single or up to 10 at once), update, and delete records — base/table/field/view pickers load from your schema automatically. |
| **HubSpot** | Get, create, update, and search contacts; create a deal; create a note. |
| **Salesforce** | Run a SOQL query, or get, create, and update any object record. |
| **Close.io** | Create or update a lead, create a contact, create an opportunity, create a note, and search. |
| **HighLevel** | List/get/create/update contacts, create an opportunity, create a note, plus calendar reads and appointment writes — list calendars, get free slots, create, update/reschedule, and cancel. |
| **Pipedrive** | List/search/get/create/update persons, create a deal, add a note. |
| **Zoho CRM** | List, search, get, create, and update records in any module. |
| **Attio** | List/filter, get, create, and update people, companies, or custom-object records. |
| **Keap** | List/search/get/create/update contacts, create an opportunity, create a note. |
| **Twenty CRM** | List/filter, get, create, and update records — hosted or self-hosted. |
Example: after **On Call Completed**, use a HubSpot update to log `{{data.analysis.success}}` on the matched contact, or branch on it first with **Condition**.
**Vendor & generic MCP.** Instead of fixed fields, these hand a prompt and the run's context to an agent that picks the right tool and arguments itself — useful when the exact call varies run to run. Both bill workspace AI credits for the agent's reasoning.
| Step | What it does | Key fields | Example |
| ----------------------------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------ | --------------------------------------------------- |
| **Supabase / Neon / Brevo / Atlassian / Shopify · Call MCP tool** | Calls that provider's own official MCP server through a saved connection. | Connection, allowed tools (optional whitelist), agent prompt | "List overdue Jira tickets and note the oldest one" |
| **MCP · Call tool** | Same agent-picks-the-tool pattern, for any MCP server saved as a connection. | Connection, allowed tools, agent prompt | "Add `{{last.email}}` to the CRM as a new contact" |
**Connected apps (Beta).** Beyond the platforms above, the catalog also carries every app your workspace has connected over OAuth. Connect one under **Connections → Add Connection → Browse apps (Beta)**, then pick it as a trigger or action like any built-in platform. Requires workspace **Beta Features**. See [App Catalog](/automations/app-catalog) for the full list and how connecting works.
| Step | What it does | Key fields | Example |
| -------------------------------- | ------------------------------------------------------------------------------- | ----------------------- | --------------------------------------- |
| **Execute app tool (Beta)** | Runs one tool from a connected app; its fields load from the tool's own schema. | App connection, tool | Create a row in a connected spreadsheet |
| **App event (Beta)** *(trigger)* | Fires when a connected app delivers a signed event. | Picked from the catalog | Start a run on a new inbox message |
## How data flows between steps
Every field marked with a ⚡ accepts `{{ }}` templates pulled from the run's current data.
| Pattern | Resolves to |
| ---------------------------- | ----------------------------------------------------------- |
| `{{data.from_number}}` | A field from the trigger's payload |
| `{{steps..}}` | An output field from a specific earlier step |
| `{{last.}}` | An output field from the step immediately before this one |
| `{{item}}` / `{{index}}` | The current item / position inside a **Loop on Items** body |
* **Extract Fields** returns its values twice — nested under `fields` (`{{steps.step1.fields.email}}`) and flattened onto the step itself (`{{steps.step1.email}}`) — use whichever reads more clearly.
* **Set variable** writes into the run itself rather than a step's own output — reference the path you chose the same way afterward, e.g. `{{vars.summary}}`.
* **Condition**, **Switch**, and **Loop on Items** also decide which connected path runs next — drag separate connections out of their `true`/`false`, per-case, or **Loop**/**Done** handles.
Use **Insert Variable** to browse what's available instead of typing paths by hand. Each step's Test panel has two levels: **Connect Test** only checks your fields are valid; **Run test** executes the step for real and fills Insert Variable with live outputs for every later step.
Run test is a real execution, not a simulation — on connected apps, email, SMS, HTTP, and CRM steps it can create or change real data.
## Statuses
| Status | Meaning |
| ------------ | ------------------------------------------------------------------- |
| **Draft** | Not live — triggers never start a run. Safe to keep editing. |
| **Live** | Active — matching trigger events start real runs. |
| **Paused** | Temporarily off. Switch it back to Live to resume. |
| **Archived** | Retired. Reactivate it the same way as Paused if you need it again. |
An automation that fails five runs in a row is paused automatically, so a broken graph can't keep firing. Check the **Runs** tab for the error, fix it, then switch it back to Live.
How an automation moves between these statuses:
```mermaid theme={null}
stateDiagram-v2
[*] --> Draft
Draft --> Live: Activate
Paused --> Live: Activate
Archived --> Live: Activate
Live --> Paused: Pause
Live --> Paused: 5 failed runs in a row (automatic)
```
## Building automations with Milian
Open an automation and ask Milian, the AI copilot, to build or change it in plain language — add a trigger and steps, wire a condition's true/false branches, rename or retag it, switch it Live, or debug a failed run, the same things you'd do by hand. Try "add an email step after the trigger," "add a condition branch and wire true/false," or "debug the last failed run."
Milian applying a change directly shows **Milian saved changes**; updating the canvas without saving shows **Milian updated the canvas — click Save to persist**, and the change stays a draft until you click **Save**.
## Next steps
Concepts, billing, and worked example automations
Browse and connect apps for triggers and actions
Keep Audience and a connected CRM aligned on a schedule
# Automations
Source: https://docs.famulor.io/automations/overview
Native workspace workflows — triggers, actions, run history, and assistant webhook binding.
The **Automations** page is the workflow builder for your workspace. Build multi-step graphs with triggers, actions, test runs, and a full run history.
Your plan determines the included monthly automation runs. Runs beyond that allowance cost extra credits at the workspace's **Automation runs** rate; current rates are on the [Usage page](https://app.famulor.io/usage).
**AI steps** such as Custom Prompt, Extract Fields, and MCP Call Tool can use additional workspace credits. The charged amount appears in the run details and Test panel.
**Graph end:** A step with no outgoing connection completes the run successfully. Stop, Return variables, and Webhook respond end the run immediately and need no further connection.
## Automations vs. Agent Tools
Automations and Agent Tools are both ways for an assistant to act on outside systems, but at different moments. An automation is a fixed sequence of steps you (or Milian) design in advance — usually started by a background trigger like **On Call Completed**, though a Live automation can also be attached to an assistant as one callable action during a conversation (see **Calling an automation from a conversation** below). Either way, it runs the sequence you built, not something decided on the fly. For tools the assistant chooses and runs itself, live, the moment it needs them — looking something up, creating a record — see [Agent Tools](/assistants/agent-tools).
| | Automations (this page) | Agent Tools |
| --------------- | -------------------------------------- | ------------------------------------------ |
| Runs | Mostly in the background, on a trigger | Mid-conversation, while talking to someone |
| Steps chosen by | You or Milian, in advance | The assistant, as it needs them |
## Triggers
* **On Call Completed** — after a voice call ends (with analysis). Requires a **specific assistant**.
* **On Inbound Call** — when an inbound call starts.
* **Inject input variables** — provides assistant variables when a call starts. End with **Return variables**.
* **Email received** — when a new inbound email arrives.
* **Conversation started / ended** — messaging channel open / closed.
* **Message received** — every inbound message on a channel, not just the first.
* **Contact created** — a new Audience contact appears. Choose which sources trigger it: **Created manually** (the only one on by default), **CSV / file import**, **API**, and **CRM sync**. Leaving import and CRM sync off means a bulk import doesn't fire the automation for every row.
* **Incoming Webhook** — starts from the secure webhook URL shown in the trigger.
* **Booking created / cancelled / rescheduled**, **Manual**, **Schedule** (soon).
* **App events (Beta)** — connected apps such as Gmail or GitHub provide their own available triggers. Requires workspace **Beta Features**.
## Actions (plugins)
Organized as **Platform → type → action** (Famulor, AI, Time, WhatsApp, Telegram, X, HTTP, Slack, …).
* **AI:** Extract Fields, Custom Prompt
* **Time:** Delay For / Until, Get Current Date and Time, Convert Timezone, Format
* **Logic:** Condition, Filter, Switch, Random, Stop, Note, Set variable, Run Code, **Loop on Items**
* **Contacts:** Create/Update, Get by phone, List, Add tags/attributes
* **Calls:** Call Phone Number
* **Messaging:** SMS, workspace email, **Send Email (SMTP)** through a saved SMTP connection, channel messages on open conversations, and approved WhatsApp templates to E.164 numbers. The builder shows which actions use workspace messaging credits.
* **Knowledge:** Add / Delete / Get source
* **HTTP / webhooks:** HTTP Request, Slack / Discord / Teams Incoming Webhooks, **Webhook respond** (sync HTTP status/body for inbound webhooks)
* **CRM / SMTP / MCP connections:** reusable credentials under **Automations → Connections**. **Test Connection** verifies an SMTP relay and sends a test message to the configured address. Available integrations are listed in the connection picker.
* **Connected apps (Beta):** choose **Browse apps** in Connections to connect an available app. Its supported tools and triggers appear in the builder after connection. Requires workspace **Beta Features**.
* **Airtable actions:** List, **Find record**, **Search records**, **Find or create**, Get by id, Create / Create records (batch ≤10), Update, Delete.
* **MCP:** Call tool — connection + tool multi-select (or all) + agent prompt with flash variables; the agent picks the tool and fills arguments
* **Variables:** Return variables (for `call.variables`)
See the [Automation node reference](/automations/nodes) for every trigger and action's exact fields and behavior.
## Example automations
A trigger and a couple of actions are usually enough:
| Goal | Trigger | Steps |
| ---------------------- | ----------------- | --------------------------------------------------------------------------------------- |
| Follow up after a call | On Call Completed | **Condition** on the call outcome → **Send WhatsApp Template** (or SMS) with next steps |
| Greet a new contact | Contact created | **Send WhatsApp Template**, or **Call Phone Number** to start a qualification call |
| Remind about a booking | Booking created | **Delay Until** the day before → **Send WhatsApp Template** with the appointment time |
Start with one trigger and one action, confirm it behaves the way you expect, then add branching. Reference trigger and step data (`{{data.call_id}}` from the trigger, `{{steps.step1.output}}` from an earlier step) instead of hardcoding values, branch with **Condition**/**Filter** rather than assuming an external call always succeeds, and use **Run test** on each step while you build — it runs against the connected app for real and fills Insert Variable with the actual output.
## Organizing automations
Automations support free-form **tags** for filtering and show the selected **assistant** when a trigger is assistant-specific. Create or update them through the UI, `POST/PATCH /api/v1/automations`, or MCP (`create_automation` / `update_automation`).
## Runs & failure alerts
The list page has **Automations** and **Runs** tabs. Use **Alert settings** to set a workspace inbox for failed runs and toggle alerts on/off.
When no custom email is set, alerts go to the workspace's configured support recipients and owners or admins. You can enable or disable failure alerts for each automation.
## Calling an automation from a conversation
An assistant can call an automation as a tool while a conversation is still in progress, not only once it ends. Under **Assistant → Settings → Automations → During conversation**, create an assistant-callable automation and describe, in plain language, when the assistant should use it — a free-text field the assistant reads before deciding to call it. The link connects automatically; build out the automation's steps, map its response, then switch the automation **Live**, since the assistant only calls automations that are Live.
This works the same way across voice, web chat, messaging, and email conversations, and an assistant can have more than one callable automation, each with its own description. Creating or unlinking one is an owner or admin action. It's separate from **On Call Completed** and the inbound triggers above, which fire outside the conversation instead of being called by the assistant itself.
## Assistant webhook binding
In the assistant Webhook card, choose **Automation** delivery and select an **On Call Completed** automation, or keep a custom HTTPS URL.
## Troubleshooting
**A WhatsApp step fails to send.** **WhatsApp Send Message** only works inside an already-open conversation (Meta's 24-hour service window). To reach someone outside it, use **Send WhatsApp Template** instead, and confirm that template is already approved for the sender you selected. See [WhatsApp](/channels/whatsapp#the-24-hour-window-and-templates) for the full window and approval rules.
**A step fails with an invalid number.** Actions expect E.164 (`+`) — add a country code before passing a national-format number through.
**A connector step fails on every run.** The underlying connection is likely disconnected or its token has expired. Reconnect it under **Automations → Connections**.
# Dialer, retries & compliance
Source: https://docs.famulor.io/campaigns/dialer-and-compliance
Parallel dialing, retry logic, calling windows, DNC lists, and voicemail handling
The dialer keeps running after you close the browser and places calls within your campaign rules.
## Parallel dialing (concurrency)
* Set **Parallel calls (concurrency)** per campaign. The slider ends at your workspace's available **Concurrent Lines**, including purchased add-ons. Workspaces with unlimited lines use a number input.
* New settings cannot exceed the current workspace allowance. If the allowance later falls, active dialing respects the lower limit. Lines are shared by every live assistant session — inbound and outbound calls, web calls, WhatsApp voice, and web chat. Campaigns wait for a free line without consuming a lead's retry attempts. Calls start in batches, so the selected concurrency is a ceiling rather than a promise that all calls start at once.
* The small info icon explains this allowance and links to **Settings → Plan** to add Concurrent Lines.
* **Concurrent Lines** is a paid, tiered add-on bought from **Settings → Plan** for workspaces that need more simultaneous capacity than the plan includes. Each purchased line raises the workspace ceiling by one.
* Calls that never connect are cleared automatically so they do not occupy a slot indefinitely.
This is a different limit from the [daily outbound call cap](/telephony/outbound-limits): concurrency governs how many calls run at the same moment, the daily cap governs how many calls may start over a whole day.
## Retry logic
Unanswered leads are retried automatically:
* **Max. retries** counts *additional* attempts after the first dial. The default is 2, so a lead is dialed up to three times.
* **Retry delay (min)** is the wait before the next attempt (default 60) — the retry lands at a *different time of day*, which measurably improves reach.
* A lead that answers stops being retried; `busy`, `no answer`, and `failed` outcomes schedule the next attempt until the budget is exhausted.
* The full attempt history is visible per lead.
**Max. retries** is the hard ceiling for every retry policy below. The voicemail and goal options cannot create unbounded loops; once the attempts are exhausted, the lead receives its final outcome.
### Retry on voicemail
Turn on **Retry on voicemail** to retry calls that reach a voicemail or unavailable mailbox, within the maximum retries. A completed conversation with an interactive receptionist is evaluated using the configured goal; an IVR classification alone does not trigger another call.
### Retry until the goal is achieved
Two settings work together to keep dialing a lead until a defined outcome is met:
* **Retry until goal completed** ("Continue calling until the goal is achieved") — marks a lead completed only when the selected goal evaluates to true; otherwise another attempt is scheduled within the maximum.
* **Goal variable** — pick one of the assistant's yes/no post-call evaluation fields, or the built-in **Call successful** result. If the list is empty, add a boolean field under the assistant's [Analysis](/assistants/analysis) tab first.
If the goal is never achieved, the lead is retried only until **Max. retries** is reached.
## Calling windows
Define **when the campaign may dial**, per weekday, in the campaign's **timezone** — e.g. Mon–Fri 09:30–18:00. Outside the window the dialer pauses and resumes automatically.
In Germany, unsolicited calls outside reasonable hours violate the UWG. Calling windows aren't just a courtesy feature — configure them for every campaign that dials consumers.
## Do-not-call (DNC)
A central workspace suppression list hard-blocks opted-out contacts before
proactive marketing outreach:
* **Universal mode** blocks every linked channel after an opt-out on any one
channel.
* **Per-channel mode** blocks only the channel where the opt-out was received.
* Phone, email, contact identity, scope, source, reason, and the mode at
opt-out are retained for auditability.
* Campaign dialing checks the active voice suppression immediately before
dispatch and fails closed when consent status cannot be verified.
Manage the mode and records under **Settings → Data → Suppression**. See
[Consent & compliance](/settings/consent-compliance) for cross-channel
behavior, restoration semantics, REST examples, and MCP tools.
* `GET /api/v1/suppression-list` — list active records
* `POST /api/v1/suppression-list` — record an opt-out
* `DELETE /api/v1/suppression-list/{id}` — restore consent without deleting
the audit history
The same operations are available through MCP.
## AMD & voicemail
Turn on **Answering machine detection (AMD)** in the campaign's settings to detect a machine before the assistant speaks, and pick **Conservative** (fewer false hang-ups) or **Aggressive** (faster detection at higher volume). AMD classifies who picked up into one of five categories:
| AMD result | Meaning |
| --------------------- | ------------------------------------------------------------------------ |
| `human` | A person answered — the conversation proceeds normally |
| `uncertain` | Couldn't be classified — treated like a human, the conversation proceeds |
| `machine-vm` | Voicemail / answering machine |
| `machine-ivr` | An IVR / phone menu system |
| `machine-unavailable` | Number unavailable / operator message |
Campaign calls use **On voicemail** and **Voicemail message** in Campaign Settings. These override the assistant for that campaign. Direct calls use [Assistant settings → Conversation → Voicemail](/assistants/conversation-quality#voicemail). An empty message falls back to the greeting. A message counts as left only when playback finishes. An unavailable mailbox cannot receive a message.
Automatic IVR navigation enables detection and presses menu digits when workspace Beta Features are enabled. With navigation off, an interactive receptionist remains on the normal conversation path. Call Screen handling takes priority. Turning campaign AMD off disables detection unless automatic IVR navigation or Call Screen handling is enabled.
The AMD result appears with the call and helps retry logic distinguish a mailbox from an unanswered call. Turn on [Retry on voicemail](#retry-on-voicemail) when appropriate.
A voicemail message followed by a retry at a different hour can improve reach. Pair the assistant's voicemail message with **Retry on voicemail**.
Put together, one dial attempt for a lead follows this path:
```mermaid theme={null}
%%{init: {'flowchart': {'defaultRenderer': 'elk'}}}%%
flowchart TD
Dial["Dial lead — attempt N"] --> Outcome{"Dial outcome"}
Outcome -->|"AMD: human or uncertain"| Talk["Conversation proceeds normally"]
Outcome -->|"IVR"| Talk
Outcome -->|"AMD: machine-vm / machine-unavailable"| VM{"Did the call finish
successfully?"}
Outcome -->|"busy / no answer / failed"| Budget{"Attempts left under Max. retries?"}
Talk --> GoalToggle{"Retry until goal completed ON?"}
VM -->|"No — it hung up"| Budget
VM -->|"Yes"| VMToggle{"Retry on voicemail ON?"}
VMToggle -->|"Yes"| Budget
VMToggle -->|"No"| GoalToggle
GoalToggle -->|"No"| Done["Lead marked completed —
no further attempts"]
GoalToggle -->|"Yes"| GoalCheck{"Goal variable true?"}
GoalCheck -->|"Yes"| Done
GoalCheck -->|"No"| Budget
Budget -->|"Yes"| Next["Schedule next attempt after Retry delay"]
Next --> Dial
Budget -->|"No"| Final["Lead gets its final outcome —
retries exhausted"]
```
## Troubleshooting
### Campaign won't start
| Message | Cause | Fix |
| --------------------------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------- |
| "The campaign has no assistant assigned." | No assistant is selected on this campaign | Assign an assistant in the campaign's settings |
| "The campaign has no leads." | The lead queue is empty | [Import leads](/audience/importing-contacts) or assign contacts from Audience |
| "Archived campaigns cannot be started. Restore it first." | The campaign was archived | Restore the campaign, then start it |
| "This campaign is blocked by your current plan limit. …" | You're over your plan's campaign allowance | Upgrade your plan, or archive another campaign |
| "Campaign is already running." | The campaign is already dialing | Nothing to do — to change its settings, select **Stop** first, then start it again |
A scheduled campaign runs through the same checks when its start time arrives. If one of them fails, the campaign moves to Paused instead of Running and keeps the error — so a campaign that was Scheduled yesterday and is Paused today usually hit one of the rows above.
### No calls happening
A running campaign that isn't placing calls usually comes down to one of these:
* **Outside the calling window** — check the current time against the campaign's [calling window](#calling-windows) and timezone.
* **Queue exhausted** — every lead has either used up its **Max. retries** or is waiting for its next retry. Import more leads, or review the [retry settings](#retry-logic).
* **Suppressed** — leads on the [do-not-call list](#do-not-call-dnc) are skipped, not retried.
### Goal-completion debugging
If [Retry until goal completed](#retry-until-the-goal-is-achieved) marks leads complete unexpectedly — or never marks them complete — the usual cause is the goal variable itself, not the retry logic:
1. Review recent call transcripts for extraction errors on the goal variable.
2. Place a few test calls and check what the assistant actually extracts.
3. Tighten the variable's description and the prompt language around it so the criteria are unambiguous.
Starting a campaign dials its first wave immediately, and the dialer re-checks every running campaign about once a minute after that. If nothing has happened within a few minutes, work through the checks above rather than assuming it needs more time.
# Outbound playbook
Source: https://docs.famulor.io/campaigns/outbound-playbook
Who to call, when, what to say, and what to measure — a research-backed starting point for cold outreach
Outbound calling works best as a system you keep tuning, not a script you set once. This page distills published sales research into a starting playbook for your campaigns — check it against your own numbers and adjust from there.
## Who to call
Define your ideal customer profile before writing a single line of script:
* **Company fit** — size, industry, region, and technology stack.
* **Persona fit** — role, goals, pain points, and what triggered the outreach (a funding round, a new hire, a renewal date coming up).
Store these as [custom attributes](/audience/contacts#custom-attributes) on your contacts — industry, use case, funnel stage, intent signal — then [save a segment](/audience/call-qa#filter-builder-and-saved-segments) for each combination worth targeting on its own. A value proposition tailored to one segment, kept to a sentence or two, consistently beats a generic pitch aimed at everyone.
## When to call
Connect rates vary sharply by time of day, and speed of follow-up matters even more:
* **B2B**: late morning (10am–12pm) and late afternoon (4–5:30pm) local time tend to connect best; Wednesday and Thursday usually outperform Monday and Friday ([Gong](https://www.gong.io/blog/best-time-to-call/), [XANT/InsideSales](https://www.xant.ai/blog/best-time-to-call-prospects/)).
* **B2C**: 11am–1pm and 5–7:30pm local time tend to work well — avoid very early mornings and late evenings ([HubSpot](https://blog.hubspot.com/sales/cold-calling-stats)).
* **Speed beats timing**: reaching a new lead within five minutes can improve connect odds by an order of magnitude compared with waiting even an hour ([Harvard Business Review](https://hbr.org/2011/03/the-short-life-of-online-sales-leads)).
Set [calling windows](/campaigns/dialer-and-compliance#calling-windows) per campaign so dialing only happens in your best hours, and turn on [retry until a human answers](/campaigns/dialer-and-compliance#retry-until-a-human-answers) — a retry lands at a different hour automatically, which is exactly the kind of variation the data above rewards.
## What to say
Lead with listening, not pitching. The **LAER** framework, from [Carew International](https://www.carew.com/blog/the-laer-method/), keeps a call centered on the customer instead of the script:
* **L**isten — let them finish before responding.
* **A**cknowledge — reflect back what you heard.
* **E**xplore — ask what would make this relevant to them.
* **R**espond — offer a specific next step, not a generic pitch.
Calls where the rep talks less — roughly 40–50% of the time — consistently correlate with higher conversion ([Gong](https://www.gong.io/blog/talk-listen-ratio/)); the same logic applies to how long your assistant's turns run.
A handful of objections cover most calls. Keep a short response ready for each:
| Objection | A workable response |
| -------------------- | ---------------------------------------------------------------------------------------------------------- |
| "Not interested" | Ask for 20 seconds to explain, then lead with one concrete number relevant to them. |
| "Send me an email" | Ask what the two most important decision points are, then offer a short meeting once those are addressed. |
| "No budget" | Ask what the current problem is already costing them, then propose a small pilot with a clear success bar. |
| "Not the right time" | Lock in a specific callback time rather than leaving it open-ended. |
Turn these into your assistant's actual guidelines and response patterns in [Prompt writing](/assistants/prompt-writing).
## Improving the script
Treat your opening and objection handling as something to keep testing, not something to finish once:
Conversion, median call duration, and where calls drop off — start from the campaign's own [progress and delivery figures](/campaigns/overview#monitoring-a-running-campaign) and the call-level detail in [History](/monitoring/history).
For example: "a shorter opening increases appointment rate," or "naming the industry up front reduces early hang-ups."
Split your audience into two comparable segments — a [custom attribute](/audience/contacts#custom-attributes) such as `test_group` is the simplest way to do it — then run the current script and the variant as two campaigns over the same window, so nothing but the script differs.
Keep the winner, stop the losing campaign, and move on to the next hypothesis.
## What to measure
Track the funnel stage by stage rather than a single top-line number — connect rate, meeting rate, and close rate each have different levers:
| Metric | What it tells you |
| ----------------------------- | ---------------------------------------------------------------------------------------- |
| Reachability | Share of leads actually contacted |
| Median call duration | Engagement — very short calls usually mean an early hang-up |
| Appointment / deal conversion | How well a connected call turns into a next step |
| Minutes per outcome | Cost efficiency, in the [minutes and credits](/billing/minutes) your plan already tracks |
Compare cohorts — time window against time window, script version against script version, segment against segment — rather than reading a single campaign's numbers in isolation; the difference is what actually tells you something worked. Published SDR benchmark reports such as [The Bridge Group](https://www.bridgegroupinc.com/) are a useful outside reference for what "good" looks like at your stage. [Call QA averages](/audience/call-qa#call-qa-average) and [cohort QA runs](/assistants/ai-quality-assurance) add a quality signal alongside these outcome numbers.
See also [Dialer, retries & compliance](/campaigns/dialer-and-compliance) and [Prompt writing](/assistants/prompt-writing).
# Campaigns & leads
Source: https://docs.famulor.io/campaigns/overview
Reach lead lists through multi-channel outbound campaigns — call, WhatsApp, or SMS
A campaign reaches a list of **leads** through exactly one primary channel: AI phone call, approved WhatsApp template, WhatsApp Call (Beta), or SMS. Voice campaigns can send one optional WhatsApp, SMS, or **email** follow-up after all call retries fail. Email follow-up sends from the verified address assigned to the campaign assistant (Settings → Channels → Email) and is not available as a primary channel.
A campaign uses the channel you select during setup. Public API clients can select the channel explicitly when creating a campaign.
## Leads & audiences
Leads are the [Audience contacts](/audience/contacts) a campaign is actively working through — every campaign lead is a contact, but a contact only becomes a "lead" once it's assigned to a campaign's queue.
* **Import** leads via CSV or add them through the UI, API, or MCP. API and MCP additions accept an optional email address, validate and normalize it, and reject an existing phone or email identity instead of silently merging contacts.
* Each lead has a **phone number** (E.164), optional name, email, tags, and custom fields such as Company, Open amount, or Appointment date.
* Campaign mappings can use contact fields, custom fields, assistant variables, campaign-local time values, read-only system or channel values, and the previous call's analysis fields.
* In campaign lead details, contact fields and user-managed variables are editable. Runtime and channel identities are shown separately as read-only system variables.
* Every primary or follow-up action is recorded as a delivery attempt.
## Setting up a campaign
Creating a campaign runs through a three-step wizard — **Campaign**, **Settings**, **Launch** — and then you fill its queue and start it from the campaign's own page.
Name the campaign and choose its channel: Call, WhatsApp, WhatsApp Call (Beta), or SMS. The wizard only shows named resources that belong to the current workspace.
Select the assistant or sender, approved template and mappings, parallel calls, retries, and answering-machine handling. See [Dialer, retries & compliance](/campaigns/dialer-and-compliance).
Set the outreach window and timezone, choose the optional follow-up, and either finish or turn on **Schedule automatic start** for a future local date and time.
On the new campaign's page, [import a CSV](/audience/importing-contacts) or use **Assign leads** to pull from a saved Audience segment or hand-pick existing contacts — a contact already assigned to another campaign must be removed from that campaign first, after its active attempt has ended. Numbers on your [do-not-call list](/campaigns/dialer-and-compliance#do-not-call-dnc) are flagged automatically.
Select **Start** once the campaign has an assistant and at least one lead. **Stop** puts it back to Paused: no new delivery claims, while active calls and accepted sends finish normally.
A segment is a saved filter, resolved at the moment you assign it — not a live subscription. Contacts that start matching later aren't added on their own; assign the segment again to pick them up.
## Campaign status
A campaign moves through six statuses:
| Status | Meaning |
| --------- | ------------------------------------------------------------ |
| Draft | Being configured — not dialing |
| Scheduled | Set to start at a future date and time |
| Running | Actively working its queue |
| Paused | Stopped taking new leads; active calls finish normally |
| Completed | Queue is empty (or the goal was reached) and dialing stopped |
| Archived | Retired — excluded from your plan's campaign count |
An archived campaign can't be started until it's restored.
## Monitoring a running campaign
The campaign view shows primary and follow-up status, last and next activity, delivered/failed totals, and voice duration where applicable. WhatsApp Call leads can wait in **Awaiting permission** until the customer grants explicit outbound-call permission.
Switch between **List** (a searchable, paginated table) and **Board** — a drag-and-drop view of this campaign's leads grouped by [status](/audience/contacts#contact-status): Ready, Processing, Scheduled, Failed / Max retries, Completed, and Suppressed. Drag a card to **Ready** to queue it for another call, or to **Suppressed** to stop the campaign from contacting it. A lead currently being called can't be moved, and no other column accepts a drop.
By default, a campaign completes automatically when no leads remain and all calls have ended. Turn off **Auto-complete when no leads remain** to keep it ready for continuously imported leads.
## API and MCP
Use `GET/PATCH /api/v1/campaigns/{id}/leads/{leadId}` or MCP `get_lead` / `update_lead` for one lead. `GET /api/v1/variables/catalog` and MCP `list_variable_sources` list valid mapping sources. Use `GET /api/v1/campaigns/{id}/deliveries` or MCP `list_campaign_deliveries` for delivery history.
See also [Outbound playbook](/campaigns/outbound-playbook) for who to call, when, and what to say.
# Email channel setup
Source: https://docs.famulor.io/channels/email
Connect a sending domain, create addresses, and set assistant email defaults
Email is a workspace channel like [WhatsApp](/channels/whatsapp) or the [web widget](/web-widget): connect a domain once, create one or more sending addresses on it, and assign each address to an assistant. Configure it under **Settings → Channels → Email**.
Only workspace owners and admins can configure the email channel.
## Connect a domain
Enter a domain or subdomain — a subdomain such as `mail.your-domain.com` is recommended, so your main domain's existing mail setup is untouched.
At your DNS provider, add the three CNAME records (one for sending, two for authentication) and the one MX record shown for the domain. Copy buttons avoid typos, and each record shows its own status as it's picked up.
Click **Verify DNS**. Propagation can take a few minutes — if verification fails right away, wait and try again.
A domain must be verified before you can create an address on it.
## Create addresses
Once a domain is verified, create one or more addresses on it — for example `support@mail.your-domain.com` — and assign each to an assistant. One assistant answers a given address at a time; create another address on the same domain to give a second assistant its own inbox. An address can carry its own sender name, overriding the workspace default below.
## Default sender name and signature
Set a workspace-wide **Default Display Name** and **Default Signature**. Both apply to any address that doesn't set its own sender name, and to the built-in **Send email** tool when it's configured to use the workspace default. The signature supports an `{agent_name}` placeholder, replaced with the sending assistant's name at send time, so one signature template works across every assistant.
## Billing
Sending and receiving email costs credits per message, at the workspace's **Send email** / **Receive email** rate. Current rates are on the [Usage page](https://app.famulor.io/usage); see also [How usage is billed](/billing/minutes).
## History
Every email conversation — inbound and outbound — appears in [Email history](/email/history), grouped into one conversation per exchange the same way a call groups into one row.
## API & MCP
* REST: `GET`/`POST /api/v1/email/domains`, `GET`/`DELETE /api/v1/email/domains/{id}`, `POST /api/v1/email/domains/{id}/verify`, `GET`/`POST /api/v1/email/addresses`, `PATCH`/`DELETE /api/v1/email/addresses/{id}`, `GET`/`PUT /api/v1/email/settings` (`assistants:read`/`assistants:write`)
* MCP: `list_email_domains`, `connect_email_domain`, `get_email_domain`, `verify_email_domain`, `delete_email_domain`, `list_email_addresses`, `create_email_address`, `update_email_address`, `delete_email_address`, `get_email_settings`, `update_email_settings`
See also [Email history](/email/history), [Messaging channels](/channels/messaging), [How usage is billed](/billing/minutes).
# Messaging channels (Telegram, Slack, Messenger)
Source: https://docs.famulor.io/channels/messaging
Connect Discord, Teams, Google Chat, and other messaging channels to one shared assistant
Multi-channel messaging lets the same assistant answer customers on Telegram, Slack, Messenger, Microsoft Teams, Discord, Google Chat, X, and WhatsApp. Replies use text; incoming voice notes can be transcribed and images can be analyzed as described below. Phone and WhatsApp voice calls are configured separately. Every conversation lands in [History](/monitoring/history).
## Voice notes and image analysis
When a connected channel supplies an accessible audio attachment, the assistant transcribes the speech and uses it as message text. For images, image analysis creates a short description of what the customer sent, including readable text where possible. The assistant uses that description in its reply. This also applies to audio and images attached to messages in connected mailbox and support channels, such as Zoho Mail. The reply follows the channel's normal text or email format.
* The first **5 attachments per message** can be processed, with a maximum of **10 MiB per attachment**.
* In **History**, an audio attachment shows its transcript when transcription succeeds and a player when the audio is available. The transcript remains readable if playback is unavailable.
* Images appear in **History** with their available descriptions. Descriptions summarize photos or screenshots; they are not a complete OCR export. PDFs, videos and other files are not analyzed by this attachment feature.
* The channel must include the attachment or allow the connected account to download it. A filename, private preview, or inaccessible link alone cannot be transcribed. Audio and image format support and access permissions can vary by channel.
* If a file cannot be downloaded or analyzed, the message keeps its attachment information without a transcript or description; the assistant cannot use the unavailable content.
Teams file attachments require the current channel app package and a personal chat. X and SMS currently have no inbound media path. Instagram voice notes depend on the channel supplying a downloadable audio file.
To retrieve a messaging conversation, including available transcripts, image descriptions and media links, use `GET /api/v1/history/messaging/{id}` or the MCP tool `get_messaging_history_item`. Obtain the conversation ID from `GET /api/v1/history` or `list_history`. Media links expire after one hour; fetch the conversation again to refresh them. Conversation detail includes up to 500 messages in chronological order.
## Tools (voice parity)
The assistant can use the same text-safe tools as on voice:
* API tools (HTTP)
* MCP tools (workspace + assistant servers)
* Knowledge base search
* Calendar integrations (built-in engine / Cal.com / Calendly / Acuity / eTermin — HighLevel calendars are voice-only)
* Built-ins: current time, business hours, send SMS, send email, schedule callback, set variable
Voice-only actions are unavailable on text channels: call or assistant transfer, end call, DTMF/keypad, and payment-card collection.
## Prerequisites
1. Your plan includes the channel you want to connect (Telegram, Slack, Messenger, Teams, Discord, Google Chat, X, WhatsApp text / WhatsApp voice).
2. If a provider requires a webhook, use the exact URL shown after you connect the channel. Verified custom domains are supported automatically.
## Connect (product UI)
Settings → Channels → Telegram / Slack / Messenger:
1. Pick an assistant.
2. Connect with one-click where available (**Add to Slack**, **Connect with Facebook**) or paste bot credentials manually.
3. Configure conversation settings (below).
4. Save — Telegram webhooks are registered automatically; Slack/Messenger **BYO** need the shown webhook URL in their developer consoles. One-click installs require no URL copy.
### Slack — Add to Slack
Preferred onboarding (platform domain / root workspaces only — not whitelabel hosts) uses the **shared Famulor Slack app**:
1. Settings → Channels → Slack → **Add to Slack**
2. Approve the requested Slack permissions.
3. Return to the channel settings and confirm the connection is active.
Manual bot-token + signing-secret paste remains available as a fallback (per-connector webhook URL shown in Settings). Whitelabel hosts keep manual only (the shared bot would appear as Famulor).
Public API: `GET/POST /api/v1/slack/oauth` · MCP: `get_slack_oauth_config`, `start_slack_oauth`.
### Messenger — Connect with Facebook
Preferred onboarding (platform domain / root workspaces only — not whitelabel hosts) uses the **same platform Meta app** as WhatsApp:
1. Settings → Channels → Messenger → **Connect with Facebook** (HTTPS required)
2. Approve the requested permissions and select a Facebook Page.
3. Return to the channel settings and confirm the connection is active.
Manual page-token paste remains available as a fallback (per-connector webhook URL shown in Settings).
Public API: `GET/POST /api/v1/messenger/facebook-login` · MCP: `complete_messenger_facebook_login`.
## Conversation settings
Applies to every text channel:
| Setting | Default | Description |
| ---------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Response delay (seconds)** | `5` | Slider `0`–`30`. Wait after the last customer message before one reply (merges quick multi-message bursts). `0` = reply instantly to every message. |
| **Inactivity timeout (minutes)** | `30` | Minutes of inactivity after the last customer message before the conversation is marked ended. |
| **Allow re-triggering** | off | If enabled, the conversation-ended webhook can fire again when the customer resumes an ended conversation and goes inactive again. |
| **Conversation ended webhook URL** | empty | Optional HTTPS URL. Leave empty to disable. Use **Test webhook** to send a sample payload. |
### Conversation ended webhook
Three things send a `conversation.ended` delivery:
* **Inactivity** — the inactivity timeout above elapses with no new customer message (checked about once a minute).
* **Manual** — someone selects **Actions → End conversation** on an open conversation in [History](/monitoring/history).
* **Test** — you select **Test webhook** in the connector's settings; this always sends a realistic example payload, whether or not a real conversation has ended yet.
Before sending, the platform runs the assistant's configured [analysis](/assistants/analysis) fields over the transcript and closes the conversation, so the payload always carries the finished analysis rather than a partial one. By default each conversation notifies its webhook once; turn on **Allow re-triggering** if a customer can resume an ended conversation and you want a fresh notification the next time it goes inactive.
A delivery looks like this:
```json theme={null}
{
"event": "conversation.ended",
"timestamp": "2026-08-26T14:32:07.000Z",
"reason": "inactivity",
"data": {
"tenant_id": "9f86d081-0000-4000-8000-000000000020",
"conversation_id": "c1b2c3d4-0000-4000-8000-000000000010",
"platform": "telegram",
"status": "closed",
"duration_sec": 187,
"message_count": 6,
"conversation": {
"id": "c1b2c3d4-0000-4000-8000-000000000010",
"platform": "telegram",
"external_thread_id": "123456789",
"external_user_id": "123456789",
"external_user_name": "Max Mustermann",
"started_at": "2026-08-26T14:28:40.000Z",
"ended_at": "2026-08-26T14:32:07.000Z",
"last_customer_message_at": "2026-08-26T14:29:55.000Z"
},
"connector": { "id": "1b2c3d4e-0000-4000-8000-000000000030", "name": "Support Telegram", "platform": "telegram" },
"assistant": { "id": "2c3d4e5f-0000-4000-8000-000000000040", "name": "Support Assistant" },
"transcript": "Customer: Hi, I need help with my order.\nAssistant: Of course — what's your order number?",
"messages": [
{ "id": "msg-1", "role": "user", "direction": "inbound", "text": "Hi, I need help with my order.", "created_at": "2026-08-26T14:28:40.000Z" }
],
"analysis": {
"summary": "Customer asked about an order and got help finding it.",
"sentiment": "positive",
"success": true,
"success_reason": "The order was located and the delivery date confirmed.",
"data": { "order_number": "12345" },
"analyzed_at": "2026-08-26T14:32:07.000Z"
}
}
}
```
`reason` is `inactivity`, `manual`, or `test`. `conversation`, `connector`, `assistant`, `transcript`, and `analysis` are repeated at the top level of the payload too, for older receivers built against that flat shape instead of the `data` envelope. Inside `analysis`, only the parts you enabled on the assistant are present — sentiment, success plus its reason, and a `data` map of your own extracted fields; see [Analysis](/assistants/analysis) for the full shape.
Configure the target in the **Conversation ended webhook URL** field above, or with `PATCH /api/v1/messaging-connectors/{id}` / `update_messaging_connector` — each channel connector carries its own URL. To send a delivery again after the fact — for example once a re-evaluation changed the analysis — use **Resend webhooks** on the conversation in [History](/monitoring/history).
## Beta connectors
Ten additional channels connect the same way, once your workspace turns on **Beta Features** under **Settings → Workspace**: Freshdesk, Gmail, Outlook, Zendesk, ServiceNow, Intercom, Zoho Mail, AgentMail, Instagram, and Zulip. Their entries stay out of **Settings → Channels** until Beta Features is on.
Instead of pasting a bot token or app secret, you connect these through Famulor's OAuth connector flow: sign in to the account once, and Famulor keeps the connection alive. Beyond the [conversation settings](#conversation-settings) every text channel shares, a Beta connector can add:
| Setting | What it does | Where it applies |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- |
| **Reply mode** | Send the assistant's reply automatically, or save it as a draft in the mailbox for a teammate to review and send. | Gmail, Outlook |
| **Watch** | Which part of the mailbox the assistant answers: the Inbox (the default), the whole mailbox, or a single label or folder. | Gmail, Outlook, Zoho Mail |
| **Extra action** | One additional capability specific to that service — applying a label, tagging a ticket, reacting to a message, and similar. Off until you turn it on. | Every Beta connector, one action each |
| **Import existing items** | On connect, how far back to pull messages that already exist — the last hour, 24 hours, or 7 days. Defaults to new messages only. | Freshdesk, ServiceNow, Intercom, Zoho Mail, Instagram |
**Import existing items** is not a silent import: every message pulled in gets a real, automatic assistant reply. Leave it on **Only new messages** unless you want the assistant to answer your existing backlog.
## Billing
Sending and receiving messages on Telegram, Slack, Messenger, Teams, Discord, Google Chat, X, and the Beta connectors costs credits per message, at the workspace's **Messaging (sent)** / **Messaging (received)** rate — the same rate [WhatsApp text](/channels/whatsapp#billing) uses. Current rates are on the [Usage page](https://app.famulor.io/usage); see also [How usage is billed](/billing/minutes).
## Platform apps you create
| Channel | What you create | Key fields |
| ----------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Telegram | Bot via [@BotFather](https://t.me/BotFather) | Bot token |
| Slack | Famulor Slack app (Add to Slack) or BYO Slack App (Bot + Event Subscriptions) | OAuth install; or bot token `xoxb-…` + Signing secret (BYO) |
| Messenger | Platform Meta app (Connect with Facebook) or BYO Meta app + Page | Page access token, App secret, Verify token (BYO); Facebook Login for preferred path |
| Teams | Azure Bot | App ID, App password |
| Discord | Discord Application | Bot token, Public key, Application ID |
| Google Chat | GCP Chat app + service account | Service account JSON |
| X | X developer app + Activity API webhook | Consumer secret, OAuth user token (or client ID + refresh token) |
Copy the connector-specific webhook URL shown in **Settings → Channels**. Telegram configures this automatically after you save.
## Public API & MCP
* REST: `GET/POST /api/v1/messaging-connectors`, `PATCH/DELETE /api/v1/messaging-connectors/{id}`, `GET /api/v1/messaging-connectors/{id}/watch-options` (Gmail labels / Outlook and Zoho Mail folders), `POST /api/v1/messaging-connectors/{id}/ended-webhook-test`
* Slack OAuth: `GET/POST /api/v1/slack/oauth`
* WhatsApp templates: `GET/POST /api/v1/whatsapp/templates`
* WhatsApp outbound voice: `POST /api/v1/calls/whatsapp-outbound`
* MCP tools: `list_messaging_connectors`, `list_messaging_connector_watch_options`, `create_messaging_connector`, `update_messaging_connector`, `delete_messaging_connector`, `test_messaging_ended_webhook`, `get_slack_oauth_config`, `start_slack_oauth`, plus WhatsApp template/call tools
* OpenAPI tag: **Messaging** / **Calls**
## WhatsApp
Full setup (credentials, webhook fields, templates, voice toggles): **[WhatsApp (Text + Voice)](/channels/whatsapp)**.
* **Text:** WhatsApp Business chat, when included in your plan.
* **Voice:** WhatsApp calling on the same connection, when included in your plan — see [WhatsApp Voice](/telephony/whatsapp-voice).
* **Templates:** `GET/POST /api/v1/whatsapp/templates` (+ MCP tools).
* **Outbound voice:** `POST /api/v1/calls/whatsapp-outbound`.
## Email
Full setup — connect a domain, create addresses, set defaults: **[Email channel setup](/channels/email)**. Email conversations appear in [Email history](/email/history) alongside your other channels.
## SMS
A workspace number that is SMS-capable and has **Allow outbound SMS** enabled can send text through the built-in **Send SMS** tool — from an assistant mid-call or mid-chat, or as an automation step (for example, a confirmation after a call ends, or an appointment reminder). See [SMS](/api-reference/sms) for which numbers qualify and the send API.
A few practices keep SMS useful instead of annoying:
* Keep messages short and to the point — SMS has no rich formatting, and it's billed per 160-character segment (70 if you use emoji or accented characters), so length costs money.
* Include opt-out instructions where local law requires them.
* Send a test message to yourself before turning a template loose on a full campaign.
* Keep an eye on SMS spend under **Usage**, especially after changing a template or targeting a new country.
# WhatsApp (Text + Voice)
Source: https://docs.famulor.io/channels/whatsapp
Connect WhatsApp Business Cloud API for chat and platform voice calls
WhatsApp is one workspace channel under **Settings → Channels → WhatsApp**, covering text chat, platform voice calls, and message templates.
| Mode | Availability |
| ----------- | ---------------------------------------------------- |
| Text chat | Included with WhatsApp messaging access |
| Voice calls | Included with WhatsApp voice access |
| Templates | Uses the same WhatsApp Business account as text chat |
**Preferred onboarding (platform domain only, e.g. app.famulor.io):** [WhatsApp Embedded Signup](/channels/whatsapp-embedded-signup) (Connect with Meta). On whitelabel custom domains, workspaces use **manual credential paste** only.
**Marketplace numbers** (Settings → Numbers) are **PSTN/SIP** for phone voice. The same E.164 becomes WhatsApp only after Meta verifies it (OTP). Your SIP trunk settings are independent of WhatsApp Cloud API. Platform SMS helpers are SMS/MMS only — not used for WhatsApp.
## Prerequisites
Your plan includes WhatsApp text and/or WhatsApp voice.
## Product UI
1. **Connect with Meta** (Embedded Signup) — pick assistant, optional marketplace number, OTP helper for marketplace SMS
2. Or paste credentials manually (token, app secret, verify token, phone number ID, WABA ID)
3. Toggles: text / voice inbound / voice outbound
4. **Edit** a connection → WhatsApp Sender Details: the chat and outbound-voice assistants, **AI Auto-Responses**, **Keep conversations unread**, calling readiness (**Enable calling on Meta**), and the Business Profile (**About**, Description, Business Address, Business Category, logo, banner, websites, and contact emails/phones). **Sync** pushes the profile to Meta — the logo becomes your WhatsApp profile picture.
5. Select **Templates** beside a sender to open its dedicated template page. **Sync with Meta** follows every result page, imports templates created in WhatsApp Manager, and refreshes approval status. **Add template** lets you create a custom draft or browse the official template library by language with a live phone preview. Variables must be numbered contiguously (`{{1}}`, `{{2}}`, `{{3}}`) and mapped to a system variable, lead attribute, assistant variable, or custom key. URL and phone-number buttons must be configured before a library template is added.
6. Place a test WhatsApp call from the connection panel
For manual setup, copy the webhook URL shown after connecting (verified custom domains are handled automatically) and subscribe to **messages**, **calls**, and **message template status updates**. For voice, also enable calling on the phone number under **Edit → Enable calling on Meta**.
## The 24-hour window and templates
Meta only allows freeform replies inside a **24-hour service window** that opens each time a customer messages you:
* **Inside the window** — your assistant can send any message, no template required.
* **Outside the window** — you must send an **approved template**. This applies to starting a new conversation, re-engaging a customer after 24 hours of inactivity, and any notification or marketing message you initiate.
Meta sorts templates into three categories, each with a different approval bar:
| Category | Use for | Typical approval time |
| ------------------ | --------------------------------------------------------------------------------------------- | ---------------------- |
| **Utility** | Order/appointment confirmations, reminders, account notifications — never promotional content | Minutes to a few hours |
| **Marketing** | Offers, announcements, re-engagement | Hours, up to 24 hours |
| **Authentication** | One-time passwords, login/verification codes | Minutes to a few hours |
**Add template** creates Utility and Marketing templates, and the official library it browses is Utility. Authentication templates are created in WhatsApp Manager and picked up by **Sync with Meta** like any other template.
A **call-permission request** isn't a separate category — it's a `CALL_PERMISSION_REQUEST` button component added to a Utility or Marketing template to ask a customer for permission to call them over WhatsApp voice. Approval for that component is usually immediate.
Meta rejects templates that mix categories — for example, promotional language inside a Utility template. Other common rejection causes: vague example values for `{{1}}`/`{{2}}` variables (use realistic samples, not "test"), aggressive or urgent-sounding language, URL shorteners instead of your own domain, and restricted content (alcohol, gambling, adult, political, or otherwise prohibited categories).
Once a template is approved it can't be edited — create a new one instead. Keep a couple of backup templates ready for high-traffic use cases so a single rejection or disable doesn't block outreach.
## Message quality and sending limits
Meta controls how much a sender may send through two separate things.
**Quality rating** — **High**, **Medium**, or **Low**, based on how people react to your messages: blocks, spam reports, and whether they reply. It drops after a run of blocks or reports and recovers as you send relevant, requested content.
**Messaging limit** — how many customers you may start a conversation with in a rolling 24 hours. A new sender starts at the lowest tier (typically 250 customers) and Meta raises it a step at a time — 1,000, then 10,000, then 100,000, then unlimited — as you send more with a healthy quality rating. A rating that stays Low can freeze the tier or move it back down.
Replies inside an open 24-hour window don't count against the limit. Both values come straight from Meta and are shown per sender under **Edit → WhatsApp Sender Details** as **Quality Rating** and **Messaging Limit**, so build a track record of quality conversations before scaling volume.
## Campaigns
Choose **WhatsApp** in the campaign wizard to send an active sender's approved text template once per lead. Saved template bindings are prefilled and can be overridden per campaign. Mappings can use canonical contact fields, read-only channel/system variables, lead attributes, assistant variables, or a custom lead key.
**WhatsApp Call (Beta)** requires Beta Features, WhatsApp voice access, an outbound-ready sender, and an approved call-permission template selected for that sender. Business-initiated calling also depends on Meta availability, region, and explicit customer permission. Permission requests and their visible **Awaiting permission** state are handled automatically. A grant resumes the lead only while its campaign is running.
Voice campaigns may use an approved WhatsApp template, SMS, or email as their single post-retry follow-up. Successful calls, suppressed contacts, and manually paused campaigns never create that follow-up. Template sends use the same messaging credits as session WhatsApp.
## Read-receipts webhook
In **WhatsApp Sender Details**, you can configure an HTTPS endpoint that receives delivery and read-status callbacks. Every callback is signed with HMAC-SHA256 over the exact raw request body. The signature is sent as `X-Signature-256: sha256=`.
A signing secret is generated when you first save the webhook URL. Existing secrets cannot be retrieved. Use **Rotate signing secret** in the sender settings, `POST /api/v1/whatsapp/connectors/{id}/profile` with `action=rotate_read_receipts_webhook_secret`, or the MCP tool `rotate_whatsapp_read_receipts_webhook_secret`. The new `signing_secret` is shown or returned exactly once, and the previous secret stops working immediately. Store the new value before leaving the response and update your receiver before sending a test request.
## History
Every WhatsApp conversation lands in [History](/monitoring/history) alongside your other channels:
* Text conversations appear as channel **WhatsApp**.
* Voice calls appear as channel **WhatsApp voice**.
Completed text conversations remain manually replyable while Meta's 24-hour customer service window is open. After a manual reply, History asks whether to keep the conversation completed or reopen it with AI auto-replies. Reopening starts a fresh inactivity timer without extending Meta's 24-hour window.
When a customer sends a photo, your assistant automatically describes what's in it and can respond to the content as part of the conversation. Incoming voice notes are automatically transcribed and handled just like a typed message. Both the media and the resulting description or transcript are visible in the conversation.
## Billing
* Text: billed per message at the workspace's **Messaging (sent)** / **Messaging (received)** rate — the same rate [other messaging channels](/channels/messaging#billing) use. Current rates are on the [Usage page](https://app.famulor.io/usage).
* Voice: existing voice-minute credit reservation/settlement (same as phone/SIP calls)
* Meta conversation pricing: customer payment method in WhatsApp Manager (Tech Provider)
## Troubleshooting
A sender's status pill shows **PENDING**, **CONNECTED**, or **ERROR**.
Confirm you completed the full Meta signup popup and created (not reused) a WhatsApp Business account during setup, then refresh after a few minutes. Still pending after 30+ minutes: contact support with the sender ID.
Open **Edit** and read the last error. Credential problems are fixed by re-running the connect flow; a policy or quality suspension has to be addressed (usually spam-like sending behavior) and appealed through Meta.
The rejection reasons above are the usual causes; a disabled template is normally quality feedback. Create an improved version and narrow who you send it to.
Marketing templates can take the longest; create an alternate template if you need to send sooner.
Send to numbers in E.164 format, confirm the recipient has WhatsApp, check the sender is CONNECTED, and confirm you haven't hit your messaging limit.
You're outside the customer's 24-hour window; send an approved template instead.
Confirm an assistant is assigned to the sender and **AI Auto-Responses** is on, then check History for the conversation's error state.
Review what you sent right before the drop, tighten targeting, and reduce volume; both the rating and the tier recover as you send higher-quality, more relevant messages.
Allow popups for the site, clear cookies/cache, or retry in another browser; then re-run the connect flow from the start.
## Public API
* Messaging connectors: `GET/POST /api/v1/messaging-connectors` with `platform=whatsapp`
* Templates: `GET/POST /api/v1/whatsapp/templates`; use `source=library`, `language`, `limit`, and the returned `paging.after` cursor to browse the official library. `parameter_bindings` maps positions such as `1` or `header.1` to variable keys. Supply `library_template_name` plus `library_button_values` when a preset has URL or phone-number buttons. `action=update` edits drafts locally or sends component changes for an existing provider template. API and MCP clients can create the same call-permission template by supplying a `BODY` and `CALL_PERMISSION_REQUEST` component.
* Outbound voice: `POST /api/v1/calls/whatsapp-outbound`
* History AI resume: `POST /api/v1/history/actions` with `action=resume_ai`, `kind=messaging`, and the conversation ID
* Calling management: `GET /api/v1/whatsapp/calling` reads readiness (Meta call settings, webhook subscription, quality rating) for a connector's business number; `POST /api/v1/whatsapp/calling` runs `enable_calling`, `resubscribe`, or `ensure_voice`.
* Sender assets: `POST`/`DELETE /api/v1/whatsapp/connectors/{id}/assets` upload or remove a Business Profile logo/banner (URL or base64).
* Sender profile and read receipts: `GET`/`PATCH`/`POST /api/v1/whatsapp/connectors/{id}/profile` manages the sender profile, tests the signed callback, and rotates its signing secret.
* Messenger Connect can also be driven entirely through the API: `POST /api/v1/messenger/facebook-login/pages` lists the Facebook Pages a user access token can manage, ahead of `POST /api/v1/messenger/facebook-login`.
* MCP: WhatsApp template tools + `start_whatsapp_outbound_call` + `get_whatsapp_calling_status` + `manage_whatsapp_calling` + `rotate_whatsapp_read_receipts_webhook_secret` + `upload_whatsapp_sender_asset` / `delete_whatsapp_sender_asset` + `list_messenger_facebook_pages`
The marketplace-number **OTP capture** session (the phone-number-verification step that turns a purchased number into a WhatsApp-capable one) stays dashboard-only — it's an interactive telephony flow with no REST/MCP equivalent.
See also [Embedded Signup setup](/channels/whatsapp-embedded-signup), [Messaging channels](/channels/messaging), [WhatsApp Voice](/telephony/whatsapp-voice).
# Connect WhatsApp with Meta
Source: https://docs.famulor.io/channels/whatsapp-embedded-signup
Connect a WhatsApp Business account inside Settings → Channels → WhatsApp
Use **Connect with Meta** to link a WhatsApp Business account without copying credentials manually. Complete Meta's sign-in, choose the business account and number, and finish phone verification in the popup.
Manual credential entry remains available when one-click connection is not available for your workspace.
Embedded Signup v2 is deprecated on **October 15, 2026**. Use v4 configurations only.
## Connect your WhatsApp account
**Settings → Channels → WhatsApp**
1. Pick an assistant
2. Optionally select a marketplace number; an SMS-capable number is easiest to verify
3. If you select an eligible marketplace number, the verification code appears in the setup flow
4. Click **Connect with Meta** → complete the popup
5. Confirm that the connected sender is active, then assign an assistant
6. Add a **payment method** in WhatsApp Manager before high-volume messaging
## Marketplace numbers + OTP
| Number type | Meta OTP | Our helper |
| ---------------------- | ------------------------ | ------------------------------------------ |
| Marketplace with SMS | SMS to the number | OTP session captures SMS, shows code in UI |
| Marketplace voice-only | Voice call | Prefer an SMS-capable number when possible |
| Customer-owned SIM | SMS/voice to their phone | User enters OTP in Meta popup |
While a voice-delivered OTP capture session is open — up to 20 minutes, or until you finish or cancel it — inbound calls to that number are answered by a silent listener instead of your assigned assistant. Normal routing resumes automatically the moment the session ends.
The code Meta reads out is shown live on this screen only. No assistant call is created and nothing is written to call history — the carrier delivers the code directly. The code is discarded when the session ends, so restart verification to get a new one if you miss it.
Buying a number in **Settings → Numbers** never auto-enables WhatsApp.
Marketplace-number verification is completed interactively in the dashboard. Other WhatsApp resources can be managed through the public API and MCP as described in [WhatsApp (Text + Voice)](/channels/whatsapp#public-api).
## Related
* [WhatsApp (Text + Voice)](/channels/whatsapp)
* [Messaging channels](/channels/messaging)
* [WhatsApp Voice](/telephony/whatsapp-voice)
* Meta: [Embedded Signup](https://developers.facebook.com/docs/whatsapp/embedded-signup/) · [Tech Provider onboarding](https://developers.facebook.com/docs/whatsapp/embedded-signup/onboarding-customers-as-a-tech-provider)
# Email history
Source: https://docs.famulor.io/email/history
Review assistant email conversations alongside calls.
Assistant emails appear in **History** as soon as an inbound message arrives. The complete exchange is grouped into one conversation row, like one call: customer → assistant → customer → assistant.
Replies are grouped through standard email threading headers and a reply-address fallback, so the full exchange stays together even across multiple messages.
## Email history table
Use **Type → Email** to show email only. Direction describes how the conversation started: an inbound customer message stays inbound after the assistant replies, while a standalone outbound email is outbound. Search matches email addresses, subjects, and plain-text bodies; the assistant and status filters work across calls and email.
Email reply states use the shared History statuses:
| Email state | History status |
| --------------------- | -------------- |
| Reply pending | `in_progress` |
| Reply sent | `completed` |
| Outbound email | `completed` |
| Reply failed | `failed` |
| No assistant assigned | `skipped` |
Open an email row to read every inbound message and assistant reply chronologically, plus sender, recipient, subject, assistant, latest reply state or error, and attachment information. Inbound audio attachments can be transcribed, and image analysis can create short descriptions of photos or screenshots, including readable text where possible. The assistant uses those transcripts and descriptions in its reply. Up to five audio and image files combined per message can be processed, with a maximum of 10 MiB per file. Their available audio players, images, transcripts and descriptions appear in the conversation. Image descriptions are summaries, not complete OCR exports; PDFs, videos and other files are not analyzed by this attachment feature and retain metadata only. Previously received attachments without retained media remain metadata only. Search also matches every grouped reply. A new reply moves the conversation back to the top.
## API and MCP
* REST: `GET /api/v1/history` and `GET /api/v1/history/emails/{id}` (`calls:read`)
* MCP: `list_history` and `get_email_history_item`
The list endpoint supports `type`, `direction`, `status`, `assistant_id`, `campaign_id`, `search`, `from`, `to`, `limit`, and `offset`.
The email **channel itself** — sending/receiving domains, per-address assistant assignments, and the workspace default sender name and signature — is also fully manageable via API and MCP: `GET`/`POST /api/v1/email/domains`, `GET`/`DELETE /api/v1/email/domains/{id}`, `POST /api/v1/email/domains/{id}/verify`, `GET`/`POST /api/v1/email/addresses`, `PATCH`/`DELETE /api/v1/email/addresses/{id}`, and `GET`/`PUT /api/v1/email/settings` (`assistants:read`/`assistants:write`). MCP tools: `list_email_domains`, `connect_email_domain`, `get_email_domain`, `verify_email_domain`, `delete_email_domain`, `list_email_addresses`, `create_email_address`, `update_email_address`, `delete_email_address`, `get_email_settings`, `update_email_settings`.
See also [Conversation history](/monitoring/history) and [Email channel setup](/channels/email).
# Enterprise
Source: https://docs.famulor.io/enterprise
Dedicated support, higher concurrency, and a hands-on rollout for high-volume voice AI
Enterprise plans build on everything in a standard workspace, with the support and capacity that high-volume phone operations need.
## What's different
* **Dedicated, hands-on support** with SLA commitments, instead of standard email support
* **Higher concurrency** for high-volume inbound and outbound calling
* **A working setup built around your own phone lines and data** — not a generic walkthrough
## What an enterprise call covers
We build a working assistant for one of your real inbound or outbound flows, on the call itself.
GDPR/DSGVO, EU hosting in Frankfurt, and SOC 2 controls — how Famulor fits regulated environments. See the [Trust Center](/support/trust-center) for the full detail.
How Famulor plugs into your CRM, CCaaS, and existing systems, and what a phased rollout looks like for your team.
## Compliance at a glance
* GDPR / DSGVO compliant
* EU hosting (Frankfurt)
* EU AI Act ready
* SOC 2 Type II (in progress)
Full commitments, technical safeguards, and how to request a DPA are on the [Trust Center](/support/trust-center) page.
## Get started
Talk to the team about your expected call volume, regions, and integration scope:
Book a call — replies within one business day.
Prefer email? Send your requirements directly.
# FAQ
Source: https://docs.famulor.io/faq
Quick answers on getting started, telephony, pricing, compliance, and enterprise use
Answers to common questions about setting up Famulor's AI voice assistants, phone numbers and call latency, pricing and compliance, and white-label or enterprise use.
## Getting started
Famulor is built for teams automating inbound or outbound voice work with AI — from a straightforward appointment line to a multi-step qualification and transfer flow. See [Assistants](/assistants/overview) for the range of what one assistant can do.
No — you can build an assistant from the dashboard with a system prompt or the visual [flow builder](/flow-builder/overview), and connect it to your other tools through [Automations](/automations/overview), all without writing code. For deeper integrations, the [REST API](/api-reference/introduction) and [MCP endpoint](/mcp/overview) are available when you need them.
Yes — you can connect a CRM or other app as a reusable [Automation connection](/automations/overview), connect a scheduling provider under [Calendar & booking](/assistants/calendar-booking) so assistants can book mid-call, give an assistant a callable tool from [Agent Tools](/assistants/agent-tools), or connect an external MCP server for a whole toolset in one step.
## Phone numbers & telephony
Yes — you can [bring your own SIP trunk](/telephony/sip-trunks) to keep your existing numbers, [import numbers in bulk from a supported carrier](/telephony/carrier-import), or [buy a new number](/telephony/phone-numbers) directly in the platform.
Latency is shaped mainly by your assistant's [engine mode](/assistants/engine-modes): Realtime is the fastest, Pipeline trades a little speed for the most control, and Half-Cascade pairs realtime listening with the voice you choose. Network quality and prompt or tool complexity also affect latency, so test with a real [voice call](/quickstart#2-test-it-in-the-browser) before going live.
Yes — concurrency and daily call limits both scale with your plan. These are two different limits: see [Outbound call limits](/telephony/outbound-limits) for the daily cap and how to request an increase, and [Concurrent Lines](/campaigns/dialer-and-compliance#parallel-dialing-concurrency) for how many calls can run at once and the paid add-on that raises it.
## Pricing & compliance
Usage is billed from a prepaid credit balance: your plan includes credits that renew with each billing period, and top-ups cover anything beyond them. See [How usage is billed](/billing/minutes) for exactly what a call consumes and how it's charged.
Famulor gives you the controls: a [configurable consent announcement and recording toggle](/assistants/conversation-quality#consent), [universal or per-channel opt-outs and suppression lists](/settings/consent-compliance), [data retention windows](/settings/data-retention), and [quiet hours per channel](/settings/dark-windows). Final legal and regulatory validation for your jurisdiction and use case should still go through your own legal/compliance team.
## Enterprise & white-label
Yes — any workspace can be granted the white-label entitlement to run under its own domain, branding, and pricing, and resell to its own customers. See [White-label administration](/admin/tenants-and-whitelabel).
Yes — enterprise plans can include dedicated support channels and SLA commitments. See [Support → Enterprise support](/support#enterprise-support) for what's included and how to get started.
# Flow builder best practices
Source: https://docs.famulor.io/flow-builder/best-practices
Patterns that make flows reliable in production
Practical patterns for building reliable [flows](/flow-builder/overview): labeling edges, structuring agents, validating data, and testing before you ship.
## Write clear edge labels
Write edge labels as clear **conditions from the caller's perspective**:
* ✅ `caller confirms they are an existing customer`
* ✅ `caller wants to cancel or reschedule`
* ❌ `yes`, `path A`, `continue`
Make sibling labels **mutually exclusive** and cover the realistic cases. If two labels overlap, routing becomes a coin flip.
## Keep agents small and single-purpose
One agent = one job (qualify, answer billing questions, book). Short, focused instructions per agent outperform one mega-agent with a wall of text. Handoffs are cheap — use them.
## Validate data with collect nodes, not prompts
Emails and phone numbers transcribed from speech are noisy. [`collect`](/flow-builder/nodes#collect) nodes confirm and validate ("Was that m-e-y-e-r?") and only proceed on success. Always name the **variable** clearly (`callback_phone`, not `var1`) — those names surface in webhooks and call details.
## Design the failure paths
* Give `collect` nodes a `failed` edge that leads somewhere sensible (a human transfer or a polite goodbye).
* Set warm-transfer `fallback` deliberately: `continue` for optional handovers, `cold_transfer` when the caller *must* reach someone.
* End every branch with an `end` node with a proper farewell.
## Test with web calls, watch the events
Run [test calls from the browser](/quickstart#2-test-it-in-the-browser) after each change. In the call detail view, the event log shows node transitions, tool calls, collect results, and transfer outcomes — read it like a stack trace when the flow misbehaves.
## Use asynchronous tools for slower requests
For slow webhooks, enable **Run asynchronously** and configure filler phrases so the conversation can continue while the request runs. See the [tool node](/flow-builder/nodes#tool).
## Start from the prompt, graduate to the flow
Prototype behavior with a plain [system prompt](/assistants/overview) first. When the call develops distinct phases or needs guaranteed data capture, move that structure into a flow — agent nodes with empty instructions inherit the system prompt, so migration is incremental.
# Flow node reference
Source: https://docs.famulor.io/flow-builder/nodes
Every node type in the flow builder, with its fields and behavior
This is the field-level reference for the flow builder — every node type, its fields, and how it behaves during a call. For what a flow is and how edges and labels work, start with the [flow builder overview](/flow-builder/overview).
## Start
Entry point of every flow. Defines the **greeting** and the **greeting mode**:
* `agent speaks first` — the greeting is spoken as soon as the call connects (typical inbound).
* `user speaks first` — the assistant waits for the caller (typical outbound: the callee says "Hello?" first).
## Agent
A conversational agent with its own **name**, **instructions**, and optional **voice override**. The conversation stays with this agent until it hands off along one of its outgoing edges.
* Each outgoing edge is a possible handoff; the assistant uses its label to decide. See [why labels matter](/flow-builder/overview#why-edge-and-agent-labels-matter).
* Empty instructions use the assistant's system prompt (Advanced prompt) as the base; node text is **appended**, not replaced.
* Voice override lets different agents speak with different voices.
## Condition
A forced decision point. You write a **description** of what is being decided; the assistant must choose exactly one outgoing edge based on the edge labels. Use it when routing must happen immediately.
## Tool
Runs a reusable **API or built-in tool** during the conversation and gives the result back to the assistant. Configure its endpoint, credentials, description, and reusable behavior under **Tools**.
| Field | Purpose |
| ----------------------------- | --------------------------------------------------- |
| **Name and description** | How the assistant understands what the tool does |
| **URL, method, and headers** | The HTTP request (GET/POST/PUT/PATCH/DELETE) |
| **Parameter schema** | JSON Schema for values the assistant should collect |
| **Timeout** | How long to wait for the request |
| **Announcement** | What to say when the tool starts |
| **Run asynchronously** | Continue the conversation while the tool runs |
| **Filler phrases and timing** | Rotating phrases spoken during long waits |
For long-running webhooks such as CRM writes or availability checks, enable **Run asynchronously** and add two or three filler phrases. The caller keeps a fluent conversation while the request completes.
## Transfer (blind)
Immediately transfers the call to a **phone number or SIP URI** (SIP REFER), optionally after a short **announcement**. The assistant leaves the call; there is no briefing of the receiving person.
## Warm transfer
The premium handover: the caller is put on **hold music**, the assistant dials the target (an employee), **briefs them with an AI-generated summary** of the conversation so far, and only then connects both parties. The employee can accept or decline; voicemail at the target is detected.
| Field | Purpose |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Target** | A Famulor Loop user, extension, ring group, or queue — or an external number in E.164 format or as a `sip:` URI. You can also let the assistant determine the number during the call |
| **Outbound phone number** | The number used to call the target (it needs an outbound trunk) |
| **Hold message** | What the caller hears before being put on hold |
| **Connected message** | What the caller hears once the target is on the line |
| **Briefing initial message** | The first thing the assistant says to the target |
| **Summary instructions** | How the assistant summarizes the conversation for the target |
| **Share supervisor conversation with the AI** | After a failed transfer, lets the AI use relevant supervisor consultation notes in the current call. The consultation remains in the call record regardless |
| **Ringing timeout** | How long to ring the target (5–120 seconds; default 30) |
| **Hold music** | Whether to play hold music, and which available track to use |
| **Fallback** | Continue the conversation, end the call, or make a blind transfer if the target does not answer or declines |
Warm transfer outcomes (`started` / `completed` / `failed`) are recorded as call events. After failure, the AI always receives the provider-neutral failure status. It receives supervisor notes only when sharing is enabled and the supervisor actually spoke.
## Collect
Structured data capture with **built-in validation, re-asking, and confirmation** — far more reliable than hoping the LLM transcribes an email address correctly.
* **Types:** `name`, `email`, `phone`, `address`, `date of birth`, `dtmf` (digits via keypad or spoken aloud), `credit_card` (payment card).
* **Variable** (required): the result is stored under this name and included in the `call.completed` webhook.
* **Prompt**: optional extra instructions on top of the built-in dialogue.
* **Max attempts** (default 3): after final failure, the flow takes the edge labeled `failed` if present.
* **Input length** (`dtmf`): choose an exact length or collection until the stop key. **DTMF digits** is the exact count or maximum (1–32); **Minimum digits** applies to stop-key mode. Existing nodes stay exact unless changed.
* **Timeout and stop key** (assigned **Collect Keypad Input** tool): one total deadline of 5–120 seconds and submit key `#` or `*`. Exact mode needs the fixed count; stop-key mode accepts submission after the minimum or finishes at the maximum. The stop key is not included in the result. Default: 30 seconds, including the prompt; saved timeouts stay unchanged.
* **Payment card:** requires the **Collect payment card** tool and an eligible connected Stripe account. During the call, payment details are collected securely. Only a reusable payment-method reference and non-sensitive display details are retained; the full card number and security code are never stored. Connect Stripe under **Tools → Agent Connectors** first.
## DTMF
Sends a sequence of **keypad tones from the assistant** to navigate an external IVR or phone menu. Assign a **DTMF Input** tool and configure the tones on the Tools page (`0–9`, `*`, `#`, or `A–D`, up to 32 characters). A flow node needs a configured sequence; after sending it, the flow follows the outgoing edge.
Match the sequence expected by the external menu, including `*` or `#` where required. If the IVR must respond between groups of tones, use separate Send DTMF nodes. To receive a PIN, account number, or menu choice from the caller, use a **Collect** node with type **Keypad or spoken digits** and assign **Collect Keypad Input** instead.
## End
Terminates the call, optionally speaking a **farewell** first. Always give your flows explicit endings — it produces clean call statuses and prevents the conversation from drifting after its job is done.
## Central Tool Library
**Add node** opens a searchable Tool Library. Reusable settings remain managed on the Tools page:
| Registry tool | Flow placement |
| -------------------- | ----------------------------------------------------------------------- |
| API | Generic **Tool** node |
| Call transfer | Dedicated **Transfer** node |
| Warm transfer | Dedicated **Warm transfer** node |
| DTMF Input | Dedicated **Send DTMF** node |
| Collect Keypad Input | Dedicated **Collect** node |
| Other built-ins | Generic referenced **Tool** node |
| MCP server | Assistant-wide assignment only; it is not one deterministic flow action |
Use **Edit in Tools** to change reusable settings. The change applies to every assistant and flow that uses the tool.
Tool, transfer, warm-transfer, Send DTMF, and keypad-collection nodes select a reusable tool from the Tools page. If a selected tool becomes unavailable, the node follows its configured path and the call details show the issue.
# Flow builder overview
Source: https://docs.famulor.io/flow-builder/overview
Turn a call into a graph of agents, tools, and decisions
The flow builder is a visual canvas where you design a call as a **graph**: nodes do the work, and edges define where the conversation can go next. Each Agent node handles one part of the conversation, and moving along an edge hands the conversation to the next node.
## Video tutorial (6 min)
Watch the complete walkthrough: create a Conversational flow assistant, open the builder, and learn what every node does — Pre-Call, Base Prompt, Start, Agent, Condition, Collect data, Transfer, Tool and End — plus connecting nodes, validation, saving and testing.
## Nodes and edges
* **Nodes** are steps: greet, converse, decide, call an API, collect data, transfer, end.
* **Edges** are possible paths. An agent node with three outgoing edges can hand the conversation to three different next steps.
* **The assistant chooses the path** based on the conversation and, crucially, on your **edge labels**.
## Start from a use-case template
When you create a Conversational flow assistant, the template gallery offers complete blueprints for common outcomes such as callback intake, lead qualification, surveys, concierge experiences, and website assistants. A blueprint can include:
* a ready-to-edit flow graph, base prompt, and first message;
* the expected outcome and supported surfaces, such as inbound phone, outbound phone, web voice, or AI avatar;
* a setup checklist for anything the use case still needs, such as a knowledge base, calendar, transfer destination, or web widget.
The badges in the gallery let you compare the flow size, supported surfaces, and required setup before you create the assistant. Applying a template copies the blueprint into your new assistant. It is a starting point, not a live link: later template updates do not overwrite your assistant.
An **Avatar-ready** blueprint prepares the conversation for a speaking virtual avatar on the web. The avatar is part of the web session's presentation layer, not a node in the flow graph. After creating the assistant, connect it to a web widget and choose the virtual avatar there. The picture shown on a template or assistant card is only a portrait and does not enable an animated avatar.
## Why edge and agent labels matter
This is the most important concept in the flow builder:
**Edge labels are not decoration.** The assistant uses each outgoing label to decide where to hand off the conversation. Vague labels produce vague routing.
Compare:
| Weak label | Strong label |
| ---------- | ------------------------------------------------- |
| `next` | `caller wants to book an appointment` |
| `option 2` | `caller asks about pricing or invoices` |
| `transfer` | `caller explicitly asks for a human, or is angry` |
The same applies to Condition nodes: the node's **description** explains what is being decided, and each edge label describes one outcome. The assistant must pick exactly one edge, so the labels should be mutually exclusive and cover all expected cases.
Agent node **names** matter too: they appear in handoffs and call details, so `Qualification agent` is clearer than `Agent 2`.
## A minimal useful flow
```mermaid theme={null}
flowchart TD
Start(["Start: greeting"]) --> Reception["Agent: Reception"]
Reception -->|"caller wants an appointment"| CollectName["Collect: name"]
CollectName --> CollectPhone["Collect: phone"]
CollectPhone --> EndA(["End: confirm & goodbye"])
Reception -->|"caller has a billing question"| Billing["Agent: Billing FAQ"]
Billing --> EndB(["End"])
Reception -->|"caller asks for a human"| Warm["Warm transfer: +49..."]
Warm --> EndC(["End"])
```
## Flow variables
Collect nodes store results in **flow variables** such as `customer_phone`. Variables are included in the public `call.completed` webhook and the call details, so connected systems receive structured data, not just a transcript. Send DTMF nodes perform an action and continue along their outgoing edge; they do not create a result variable.
## Fallback behavior
* An Agent node with **empty instructions** uses the assistant's Advanced prompt as its base. Node-specific instructions are added to that base.
* A Collect node that fails after its retry allowance takes the outgoing edge labeled **Failed** if one exists, otherwise the normal edge.
* If a flow step cannot run, the call follows the available fallback path and records the issue in the call details.
Continue with the [node reference](/flow-builder/nodes) and [best practices](/flow-builder/best-practices). For when to reach for a flow instead of a plain prompt, see [System prompt vs. flow builder](/assistants/overview).
# Voice AI glossary
Source: https://docs.famulor.io/glossary
Terms used across Famulor and voice AI in general, A to Z
Short definitions of the voice AI, telephony, compliance, and Famulor platform terms that appear across these docs, listed alphabetically. Most entries link to the page that covers the topic in full.
## A
### Agent Connectors
The searchable catalog of pre-built integrations an assistant can call during a conversation — CRMs, calendars, and other external services — attached in a couple of clicks instead of built by hand. See [Agent Tools](/assistants/agent-tools#agent-connectors).
### AI Assistant
A configured voice or chat agent: prompt or flow, engine mode, models, voice, and behavior settings. See [Assistants](/assistants/overview).
### API Key
A secret token used to authenticate requests to the Famulor API, shown once at creation (`fam_...`). Store it securely and never paste it into a chat or share it in plain text. See [API & MCP](/mcp/overview).
### Audience
The workspace's contact list — one row per person, with their combined call and message history, custom fields, and any segments they belong to. See [Contacts](/audience/contacts).
### Automation
A native workflow graph — trigger, steps, and connections to your other tools — that runs without writing code. See [Automations](/automations/overview).
## B
### Backchanneling
Short listener feedback during a conversation, such as "mhm," "okay," or "right." Famulor's adaptive interruption handling recognizes it and keeps the assistant talking through it instead of treating it as a real interruption. See [Interruption handling](/assistants/conversation-quality#interruption-handling).
## C
### Caller ID
The phone number shown to the person receiving an outbound call from your assistant — a number bought in the marketplace, a number on your own SIP trunk, or an existing number of yours verified for outbound use. See [Caller ID verification](/telephony/caller-id).
### Campaign
Organized outbound calling (or WhatsApp/SMS messaging) over a contact list, with schedules, retries, and results tracked per lead. See [Campaigns](/campaigns/overview).
### Conversation-Ended Webhook
A per-connector [webhook](/glossary#webhook) that fires a `conversation.ended` event with the transcript and the finished analysis when a text-channel conversation closes — after the inactivity timeout, when someone ends it by hand in History, or as a test send. See [Conversation ended webhook](/channels/messaging#conversation-ended-webhook).
## D
### Data Residency
Where your workspace's data is stored and processed — for example, keeping it inside the EU rather than a global default region. In Famulor, **Settings → Workspace → AI inference region** pins where a workspace's AI processing runs: Global, EU, or US. See [Trust Center](/support/trust-center#1-our-sovereignty-commitments).
### DID (Direct Inward Dial)
A direct-dial number that routes an inbound call straight to a target — an assistant, extension, or ring group — without going through a main switchboard.
### DPF (EU-U.S. Data Privacy Framework)
A legal transfer framework used for EU–U.S. data transfers by eligible, certified organizations. See [Trust Center](/support/trust-center#10-international-data-transfers--safeguards).
### DTMF
Dual-Tone Multi-Frequency: the keypad tones a caller sends by pressing a key during a call (for example "press 1"). Used for menu navigation and structured input. See the [DTMF node](/flow-builder/nodes#dtmf).
## E
### E.164
The international standard format for phone numbers (for example `+491701234567`), required by most telephony and messaging integrations.
### Endpointing
See [Speech Endpointing](/glossary#speech-endpointing).
### Engine mode
The audio architecture an assistant uses to listen and speak: **Pipeline** (separate steps, most control), **Realtime** (one continuous voice loop, fastest), or **Half-Cascade** (realtime understanding with full voice control). See [Engine modes](/assistants/engine-modes).
## F
### FQDN
Fully Qualified Domain Name — used when configuring a SIP trunk or an API endpoint.
## H
### History
The workspace's unified conversation log: calls, live chat, email, and every connected messaging channel appear here as they happen, each with its transcript, recording, and analysis. See [History](/monitoring/history).
## I
### Inbound Call
A call received by your assistant from an outside caller. See [Inbound & outbound calls](/telephony/inbound-outbound).
### Inference
Running a model to produce an output — for example, generating the assistant's next reply from the conversation so far.
### ISO/IEC 27001:2022
An international standard for Information Security Management Systems (ISMS).
## K
### Knowledge Base
A curated set of documents, FAQ entries, or crawled pages your assistant can use to answer with accurate, business-specific context instead of guessing. See [Knowledge bases](/assistants/knowledge-base).
## L
### Large Language Model
A machine-learning model trained on large amounts of text and used to understand a conversation and generate a reply, token by token.
### LLM
Abbreviation for [Large Language Model](/glossary#large-language-model).
### Loop
Short name for [Famulor Loop](/telephony/famulor-loop), the built-in business-phone system: personal extensions, presence, ring groups, queues, and registered devices.
## M
### Mid-Call Tool
A tool an assistant can call during an active conversation to fetch data or trigger an action in an external system — checking an order status, sending an SMS, or transferring the call. Platform actions live in [Built-in tools](/assistants/built-in-tools); your own reusable tools and pre-built connectors live in [Agent Tools](/assistants/agent-tools). For a whole external toolset connected in one step, see [External MCP servers](/api/tools-and-webhooks#external-mcp-servers).
### MFA
Multi-Factor Authentication: a second sign-in step (an authenticator app or an emailed code) in addition to a password. See [Account security](/account-security).
### Milian
Famulor's built-in AI copilot. Available from the dashboard and the assistant editor, it can build, explain, and change your workspace configuration in plain language. See [Milian Copilot](/assistants/milian-copilot).
### Mission
A scheduled task for Milian: a saved prompt that runs unattended on a recurring schedule or on demand, without a browser tab open. See [Milian Missions](/assistants/routines).
## O
### OAuth
An authorization standard that lets you grant a connecting application limited access to a service without sharing your password. Famulor's MCP endpoint and several Automation connections use it. See [Authentication and consent](/mcp/overview#authentication-and-consent).
### Outbound Call
A call your assistant places to an outside number — from a single test call, the API, or a campaign. See [Inbound & outbound calls](/telephony/inbound-outbound).
## P
### PBX
Private Branch Exchange: a company phone system that routes internal and external calls. See [PBX & contact center platforms](/telephony/providers/pbx-and-contact-center).
### PHI
Protected Health Information: sensitive health-related data subject to regulations such as HIPAA in the United States.
### Provisioning
The setup process for a telephony resource — buying or porting a number, connecting a SIP trunk, and completing any required regulatory verification. See [Phone numbers](/telephony/phone-numbers).
### PSTN
Public Switched Telephone Network: the traditional public telephone network used for landline and mobile calls.
## R
### Rate Limit
A technical limit on how many API requests a credential can make within a given time window.
### Retry Strategy
The policy a campaign follows when re-attempting a call that wasn't answered or reached voicemail — how many times, how far apart, and under what conditions it stops. See [Dialer, retries & compliance](/campaigns/dialer-and-compliance).
## S
### SCC (Standard Contractual Clauses)
EU-provided contractual clauses used to make international data transfers lawful. See [Trust Center](/support/trust-center#10-international-data-transfers--safeguards).
### SDK
Software Development Kit: a packaged set of libraries and tools that helps developers integrate faster.
### Server URL
An endpoint your own backend exposes so Famulor can send it real-time events, such as a `call.completed` payload. See [Tools & webhooks](/api/tools-and-webhooks#receive-call-results-with-webhooks).
### SIP Trunk
A connection between telephony infrastructure (like a PBX) and a voice service over the SIP protocol — how Famulor sends and receives calls for numbers you bring yourself. See [BYO SIP trunk](/telephony/sip-trunks).
### SOC 2 Type 2
An audit standard that evaluates how effectively an organization's security controls operated over a period of time, not just at a single point in time.
### Speech Endpointing
Detecting where a caller's speech starts and ends in an audio stream. Good endpointing avoids cutting a caller off too early and keeps turn-taking natural.
### SSO
Single Sign-On: one login used to access multiple connected systems.
### SST
Common typo for [STT](/glossary#stt).
### STT
Abbreviation for Speech-to-Text: converting spoken audio into text.
## T
### Telemarketing Sales Rule
A US regulation governing telemarketing calls and consumer protection. If you run outbound calling programs, have your legal/compliance team validate your process for each region you call into. See [Dialer, retries & compliance](/campaigns/dialer-and-compliance#do-not-call-dnc).
### TTS
Abbreviation for Text-to-Speech: converting text into spoken audio.
## V
### Voice-to-Voice Latency
The time between a caller finishing speech and the assistant's audio reply starting. A core quality metric for real-time voice AI — see [Engine modes](/assistants/engine-modes#quick-comparison) for how each mode trades off latency and control.
### VoIP
Voice over IP: telephony carried over IP networks instead of traditional circuit-switched lines.
## W
### Webhook
An HTTP endpoint that receives event data from Famulor as it happens — most commonly a `call.completed` event with the transcript, duration, and extracted variables. See [Tools & webhooks](/api/tools-and-webhooks).
### WhatsApp Business Platform
The technical WhatsApp integration for businesses. In Famulor, you connect it yourself with **Connect with Meta** — Meta's own embedded sign-in flow — using either your own verified number or one from Famulor's marketplace. See [Connect WhatsApp with Meta](/channels/whatsapp-embedded-signup).
### Workspace
The shared environment for a team's assistants, calls, campaigns, channels, and settings. Plan, credits, and billing are all workspace-scoped, and one account can belong to more than one workspace. See [Workspaces](/settings/workspaces).
# Famulor overview
Source: https://docs.famulor.io/index
What Famulor's AI voice assistants do and how the platform fits together
Famulor lets you build, deploy, and operate AI voice assistants that make and receive real phone calls — and talk to visitors on your website. It is a multi-tenant, white-label platform: agencies and resellers can run it under their own domain, branding, and pricing.
Assistants work around the clock and take several conversations at the same time — up to the simultaneous-call capacity in your plan — so callers are answered instead of queued. Routine questions, bookings, and qualification happen without a person involved, and your team steps in only for the calls that actually need one.
## What you can build
A phone number that answers instantly, qualifies callers, books appointments, and transfers to humans when needed.
Automated calling campaigns with a parallel dialer, retry rules, calling windows, and voicemail handling.
Visual flows with specialized agents, conditions, data collection, HTTP tools, and warm transfers.
Embed the same assistants as a voice or chat widget on any website.
## Core concepts
| Concept | What it is |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **Assistant** | A configured AI agent: prompt or flow, engine mode, models, voice, and behavior settings. |
| **Flow** | An optional visual call script — multiple agents connected by labeled edges, plus tools, conditions, transfers, and data-collection steps. |
| **Phone number** | A number bought through the platform or brought via your own SIP trunk, routed to an assistant. |
| **Campaign** | Organized outbound calling for a contact list, with schedules, retries, and results. |
| **Knowledge base** | Documents your assistant can use to answer questions during a conversation. |
| **History** | The unified log of every conversation — calls, chat, email, and messaging — with transcripts, recordings, and outcomes. |
| **Workspace** | The shared environment for your team, assistants, channels, and settings. |
| **Plan** | The subscription that includes your workspace capabilities and usage limits. |
### How a call flows
1. **The call starts.** A caller dials your number (inbound), or the assistant places the call from a campaign, a single test, or the API (outbound).
2. **The assistant listens.** It follows what the caller says as they speak and detects when a turn is finished.
3. **It decides what to say.** Its prompt or flow, plus any tools and knowledge base it has access to, produce the next reply or action.
4. **It speaks.** The reply comes back in the assistant's selected voice.
5. **It acts.** It answers questions, collects information, books an appointment, or transfers to a person when the conversation calls for it.
6. **Everything is recorded.** The transcript, recording, and outcome land in History automatically — ready to review or build an automation on.
How steps 2 to 4 run internally depends on the assistant's [engine mode](/assistants/engine-modes): separate listening, reasoning, and speaking stages, or one continuous voice loop.
## Built for Europe
Consent announcements with optional recording are built in, and recording can begin only after the caller agrees. Calling windows and do-not-contact lists help teams follow their privacy and outreach requirements.
## Where to go next
Create your first assistant and test it with a web call in under five minutes.
Automate everything via REST or connect Claude/ChatGPT through the MCP endpoint.
# Install the web app
Source: https://docs.famulor.io/install-web-app
Install Famulor or your white-label workspace from the browser without an in-app install prompt.
The Famulor web platform can be installed as an app from a supported browser. It opens in its own window and keeps the same secure sign-in, [workspace switcher](/settings/workspaces#switching-workspaces), navigation, and [Loop softphone](/telephony/famulor-loop) as the website.
Famulor does not show an automatic install pop-up. Your browser decides when its install action is available.
## Install on desktop
In Chrome or Edge:
1. Open your normal platform or white-label sign-in domain.
2. Sign in and wait for the workspace to load.
3. Select the install icon in the address bar. If the icon is not visible, open the browser menu and choose **Install app**.
4. Confirm the installation.
The installed app appears in the operating system's app list and can be pinned like any other app.
## Install on a phone or tablet
On Android, open the site in Chrome and choose **Install app** or **Add to Home screen** from the browser menu.
On iPhone or iPad, open the site in Safari, select **Share**, then **Add to Home Screen**.
Browser support and the exact menu label depend on the device and browser version. A private browsing window cannot normally install the app.
## White-label branding
Always install from the domain you intend to use. The app name, icon, and accent color are resolved from that domain:
* the Famulor domain installs the Famulor app;
* a verified reseller domain installs that reseller's approved [white-label identity](/admin/tenants-and-whitelabel).
Each domain is a separate installed app. If branding changes later, reopen the installed app while online so the browser can refresh it. If the old icon remains, remove the app and install it again from the correct domain.
## Notifications and Loop calls
Installing the web app does not grant notification permission automatically. If your browser offers notifications, you remain in control of that permission in the browser or operating-system settings.
Keep the device online for workspace data and calls. For reliable locked-screen incoming Loop calls on iOS or Android, use the Famulor mobile app; browser background-call behavior varies by operating system.
## If the install action is missing
Check that:
* you opened the production platform domain or a verified white-label domain;
* the page uses a secure connection;
* you are not in private browsing mode;
* installation is not blocked by a company browser policy;
* the app is not already installed for that domain.
Reload the page after updating the browser. If the action is still unavailable, use the browser menu or contact your workspace administrator with the browser and operating-system versions.
# Conversation history
Source: https://docs.famulor.io/monitoring/history
Every call, chat, and message in one unified conversation log
**History** is the single record of every conversation your workspace has — phone calls, web widget voice and chat, WhatsApp text and voice, email, and every connected messaging channel — sorted by most recent activity. A conversation appears here the moment it starts, not just after it ends.
A call that is still running shows a **Listen live** button in its row when your plan includes Live monitoring. See [Live monitoring & supervisor](/monitoring/live-monitoring) for listening in, whispering, barging in, or taking over.
## The list
Each row shows the contact, the assistant that handled it, type, direction, status, duration, date, a short summary, and the contact's tags. Reply threads — every inbound and outbound turn on the same email thread or messaging conversation — are grouped into one row, so a back-and-forth reads like a single conversation instead of one row per message.
## Filtering
Narrow the list by any combination of:
* **Type** — Call, Avatar (web voice with a virtual avatar), Live chat (widget text chat), WhatsApp voice, WhatsApp, Email, or a specific messaging platform (Telegram, Slack, Messenger, Teams, Discord, Google Chat, X, plus any Beta connectors your workspace has enabled).
* **Direction** — inbound, outbound, or web.
* **Status** — queued, in progress, completed, failed, no answer, busy, or skipped.
* **Assistant** or **Campaign**.
* **Tags** — show only conversations whose contact carries a given tag. Opening History from an **Audience** contact narrows the list to that one contact.
* **Search** — matches phone numbers and call summaries, the contact name or handle on messaging channels, and email addresses, subjects, and message bodies.
Filters combine, and the list paginates underneath them. A date range isn't a filter in the app — use `from` and `to` on the API when you need one.
## Conversation detail
Open a row for the full picture:
* **Recording and transcript** (calls) — play the recording in the built-in player or download the audio file. The transcript follows the playback, and selecting a line jumps the audio to that moment. After a call you can request an **Enhanced** transcript re-generated from the recording and switch between it and the live one.
* **Input variables** — values passed into the conversation before it started (pre-chat form answers, campaign lead data, API-supplied variables).
* **Analysis** — sentiment, the success verdict with its reason, any structured fields your assistant's [post-call analysis](/assistants/analysis) is configured to extract, and the per-call **[AI QA scorecard](/assistants/analysis#ai-qa-scorecards)** (score, pass or fail, and the criteria behind it) when your assistant has scorecards enabled.
* **Webhook & Automation** — delivery status for any outbound webhook tied to the conversation, with the HTTP response.
* **Usage & cost** for that conversation.
## Actions
Select one or more rows — or act on the open conversation directly — to:
| Action | What it does |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Re-evaluate** | Re-runs post-conversation analysis (summary, sentiment, success, extracted fields) against the current transcript. |
| **Re-transcribe** | Calls only, one at a time from the open conversation. Generates the Enhanced transcript from the call recording. |
| **Resend webhooks** | Rebuilds the end-of-conversation webhook payload from the record as it stands right now and re-sends it — useful after a re-evaluate changes the analysis. |
| **Add to blacklist** / **Remove from blacklist** | Calls only. Adds or removes the contact's phone number from workspace [Suppression](/settings/consent-compliance). |
Re-evaluate and Re-transcribe consume credits — the button shows the cost before you run it. Re-evaluate bills at the workspace's **History re-evaluate** rate per run and Re-transcribe at its **Re-transcribe** rate per recorded minute; current rates are on the [Usage page](https://app.famulor.io/usage). Re-transcribe appears only for calls that have a recording and haven't been re-transcribed yet.
Messaging conversations add a few controls of their own. You can reply by hand from the conversation; **Stop AI** and **Resume AI** decide whether the assistant keeps answering — stop it to take over yourself, resume it to hand the conversation back; and **End conversation** closes it out.
On WhatsApp there's one extra step: replying by hand to a conversation that already ended prompts you to either keep it completed or **Resume AI**, which reopens it for auto-replies and restarts the inactivity timer. That's only possible while Meta's 24-hour service window is still open, and resuming does not extend that window.
## Exporting
The **Export** button downloads the current filtered page as a CSV (contact, assistant, type, direction, status, duration, date, and summary). Apply filters first to scope what's included, then export — each page of results exports separately.
Need a complete export rather than one page at a time? An MCP client that supports long-running tasks can call `export_history_task` to build a durable CSV of your full filtered history and return a short-lived download link.
## Activity notifications
Each assistant carries its own notification matrix, configured from **Assistant → Settings → Automations → Notifications**, that controls whether workspace owners and admins get an email when new activity lands in History for that assistant. The matrix has one row per channel — Calls, Avatar, Live chat, WhatsApp voice, WhatsApp, Telegram, Slack, Messenger, Teams, Discord, Google Chat, X, and Email — and a checkbox turns email on or off per channel, independently for each assistant. Every channel starts switched on, so this is a list to opt out of rather than into.
The same per-channel switch also governs the device alerts a member can turn on for their own browser or installed app under [Browser notifications](/account-security#browser-notifications).
The matrix also shows an SMS column, but it isn't active yet — every checkbox in that column is disabled.
## Related channel views
* [Email history](/email/history) covers the email-specific reading view (reply states, sender/recipient/subject, attachments) in more depth.
* [Live monitoring & supervisor](/monitoring/live-monitoring) covers listening in on and intervening in a call while it's still happening.
## API and MCP
* REST: `GET /api/v1/history` (`calls:read`) — filter with `type`, `direction`, `status`, `assistant_id`, `campaign_id`, `lead_id`, `tags`, `search`, `from`, `to`, `limit`, `offset`.
* REST: `GET /api/v1/history/emails/{id}` reads one email thread's full detail.
* REST: `POST /api/v1/history/actions` runs the actions above — `reanalyze`, `retranscribe`, `resend_webhook`, `resume_ai`, `blacklist_add`, `blacklist_remove` — on up to 50 records at a time, addressed by `kind` (`call`, `messaging`, or `email`). `retranscribe` is the exception: it takes exactly one call id per request.
* REST: `GET /api/v1/calls`, `GET /api/v1/calls/{id}`, and `GET /api/v1/calls/{id}/recording` cover the call-specific view, including the recording file, for `type: call` rows.
* MCP: `list_history`, `get_email_history_item`, `run_history_actions`, plus `list_calls` / `get_call` for the call-specific view.
# Live monitoring & supervisor
Source: https://docs.famulor.io/monitoring/live-monitoring
Watch live transcripts, listen in, whisper to the AI, barge in, or take over
Live monitoring gives supervisors real-time visibility and control over ongoing calls — useful for quality assurance, assistant improvement, and human intervention. Your plan must include **Live monitoring**.
## Live transcript
The dashboard lists all **active calls** in your workspace. Open one and the transcript streams in **live** — including interim (in-progress) transcription — so you read the conversation as it happens, with no audio needed.
## Listen (silent monitoring)
Click **Listen** to hear the call in real time:
* You join as a **hidden participant** — neither the caller nor the assistant's behavior changes; nobody hears you.
* Audio is receive-only.
* Every listen-in is **audit-logged** (who listened to which call, when).
## Whisper (coach the AI)
Send the assistant a **text instruction mid-call** that the caller never hears:
* The instruction is injected into the active agent's guidance — e.g. *"offer the 20% retention discount"* or *"wrap up, the customer is in a hurry"*.
* Optionally trigger an **immediate spoken response** so the assistant acts on your instruction right away instead of on its next turn.
* Whispers appear in the call's audit history.
## Barge-in
Need to speak yourself? **Barge in** to join the call audibly — a three-way conversation with the caller and the assistant. Useful for a quick correction without ending the AI session.
## Takeover
Full human handover: the assistant is **muted instantly** — no goodbye, no further AI speech — and you continue the conversation alone. Transcription and recording continue so the call record stays complete. The takeover appears in the audit history.
## Hang up
**Hang up** ends the call for everyone. Use it when the conversation should stop immediately — unlike **Disconnect**, which only leaves your supervisor view. The action is available in the monitoring UI, [Public API](/api-reference/introduction), and MCP tool `live_call_control`. The call record and its transcript stay available afterward in [Conversation history](/monitoring/history).
## Permissions & audit
Supervisor actions are limited to authorised workspace members when **Live monitoring** is included in the plan. Every action leaves an audit-trail entry. Ensure your use of monitoring, recording, and intervention complies with applicable law and company policy.
During [campaigns](/campaigns/overview), keep the active-calls view open with live transcripts. You'll spot prompt problems within the first handful of calls — whisper corrections in, then fix the prompt for the rest of the batch.
# Product tour
Source: https://docs.famulor.io/product-tour
A visual tour of the Famulor workspace, from your first assistant to daily operations
This tour shows the main areas your team can use in Famulor. What you see in your own workspace depends on your role and the features included in your subscription.
Use the sidebar in Famulor to move between these areas. You can return to the dashboard at any time for a quick overview.
## Dashboard and Milian
The dashboard holds two views that share the page. Milian, the in-app copilot, is embedded directly here and can help you navigate the product and work with your workspace using your existing access. **Workspace overview** is the other: expand it for your numbers and shortcuts, collapse it again to give the Milian chat the whole page. Where Milian isn't part of the workspace, the overview stays open permanently.
Workspace overview carries four stat tiles — **Total Calls**, **Active Agents**, **Talk Time**, and **Campaigns** — a row of quick actions, and the customer-reach map, a geographic view of where your calls and customers are.
The quick actions jump straight to common next steps — **Open Agents**, **New Assistant**, **Call History**, **Campaigns** — plus two one-click entry points for connecting Famulor to the rest of your stack: **Use with ChatGPT & Claude** opens the same connection helper covered in [Connect an AI client](/mcp/overview), and **Migrate from Famulor 1.0** opens the same import flow covered in [Migrate from Famulor 1.0](/settings/famulor-migration).
## Build your assistants
The **Assistants** page is the home for every voice and messaging assistant in your workspace. Create a new assistant, open an existing one, or continue refining its behavior.
In the editor, shape the greeting and conversation instructions, test the experience, and save changes from one place.
For structured conversations, the visual flow builder lets you connect steps, branches, actions, and handoffs.
Assistant settings collect the detailed choices for voice, language, behavior, tools, knowledge, and connected channels. Available options can vary by workspace.
## Review conversations
**[History](/monitoring/history)** is the shared record of calls and conversations. Filter the list to find a specific interaction, then open it for the full context.
The detail view brings the transcript, outcome, collected information, and available media together, making it easier to review performance or follow up.
## Reuse Milian Missions
[Milian Missions](/assistants/routines) package recurring jobs so they can be managed once and run reliably on schedule. They are useful for work such as recurring call summaries, lead follow-up, or daily digests.
## Know and manage your audience
The **Audience** area brings contacts and the operational records around them into one place.
The do-not-contact list helps your team honor contact preferences. Authorized team members can review and maintain entries before outreach begins.
Memory records let you review what assistants may remember about a contact and manage that information when needed.
Callbacks keep requested follow-ups visible so they can be completed at the right time.
CRM sync connects contact activity with another business system. This page appears only when the feature is available to your workspace and your role permits configuration.
## Run campaigns
Campaigns coordinate outbound work: choose an assistant and audience, prepare the schedule, and follow progress from one place.
The campaign detail view focuses on setup, current status, and results for one campaign.
The board view groups campaign work by status for a fast operational overview.
## Improve quality with AI QA
[AI QA](/assistants/ai-quality-assurance) helps teams evaluate conversations consistently, find patterns, and focus coaching or assistant improvements where they matter most. Availability depends on your subscription.
## Build a knowledge base
Add documents that assistants can use when answering questions. Keep source material focused and current for the most reliable answers.
Auto refresh keeps supported sources up to date on a schedule, reducing manual maintenance.
FAQs are ideal for concise, curated question-and-answer pairs that should be easy for an assistant to retrieve.
## Extend assistants with tools
The installed view shows the capabilities already available in your workspace and where they can be managed.
The connectors catalog lets authorized users add supported business services. Some connectors may be optional or require separate access with the connected service.
## Manage bookings
The bookings list gives your team a single view of appointments created through assistants and connected calendars.
Event types define what can be booked, including duration and availability rules.
Calendars determine where availability comes from and where confirmed appointments are stored.
Booking integrations connect supported scheduling services. These settings are visible only to roles that can manage workspace connections.
## Automate work
Automations turn recurring work into repeatable processes that can react to events and coordinate follow-up actions.
The builder provides a visual workspace for arranging triggers, decisions, and actions.
Run history shows what happened during each execution and helps authorized users investigate unsuccessful steps.
Connections are the accounts and services automations can use. Only workspace roles with configuration access can add or change them.
## Understand usage and results
The **Usage** page helps workspace owners and authorized team members understand consumption over time and the balance available to the workspace.
Custom dashboards turn workspace data into focused views for your team. Natural-language creation and advanced analytics may depend on your subscription.
## Configure your workspace
Settings are organized into focused panels. The panels available to you depend on your role and subscription.
### Workspace, team, and preferences
Workspace settings cover the name and shared identity used by your team.
Team settings let owners and authorized admins invite members and manage their access.
Preferences personalize the product experience, including appearance and other user-level choices.
### Subscription, balance, usage limits, and referrals
The plan page summarizes the workspace subscription and available options.
Balance settings help owners monitor available credit and manage supported payment preferences.
Limits make usage boundaries visible and help teams understand which capabilities are available.
The referral panel shows your referral link and earned benefits where the program is available.
### Phone, messaging, and email
Numbers settings are where authorized users manage phone numbers and their assignments.
Messaging channels bring supported text-based communication into the workspace.
WhatsApp settings guide authorized users through connecting and managing the channel when available.
Verification helps teams confirm the senders or destinations required for supported communications.
Email settings control the workspace's supported email experience and sender details.
### Memory, data, and contact controls
Memory settings define the workspace-wide behavior and visibility of assistant memory.
Custom attributes give teams a consistent structure for the information stored with contacts and conversations.
[Data retention](/settings/data-retention) lets authorized admins choose how long supported workspace data should be kept.
Suppression settings centralize contact restrictions and help prevent unwanted outreach.
[Dark windows](/settings/dark-windows) define times when automated contact should pause, helping teams respect local schedules.
### Web experiences and optional features
Web widget settings customize the assistant experience embedded on your website.
Optional connectors are shown only to workspaces that can try them. Workspace admins decide whether to enable them for the team.
### Developer access and accountability
The developer access panel is for customers who want to connect their own applications or compatible assistants to Famulor. Treat credentials as secrets and share them only with trusted team members.
The audit log helps authorized admins understand important workspace changes and who made them — see [Audit log](/settings/audit-log) for how to search it and read a single change.
## Create WhatsApp templates
Templates let teams prepare approved, reusable messages for supported WhatsApp conversations. Access depends on channel setup and your role.
## Operate a white-label business
The following area is available only to workspace owners and authorized admins with White Label access. Regular workspace members and white-label customers do not see these pages.
The white-label dashboard provides an overview of customer activity and the parts of your branded service that may need attention.
The customers list helps authorized admins find and manage the customer workspaces associated with their service.
Open a customer to review the information and actions relevant to that workspace.
Plans define the packages you present to your own customers.
Default limits provide sensible starting boundaries for newly created customer workspaces.
Usage pricing controls how usage is presented and charged within your branded offering.
Billing platform settings connect the supported billing experience for your customers. Access is restricted to authorized admins.
Voice settings let you curate the choices offered to customer workspaces.
Prompt templates give customers a branded starting point for common assistant use cases.
History gives authorized admins a support-oriented view of customer conversations while respecting the access granted to their role.
Live monitoring is an optional operational view for authorized white-label admins. Use it only in line with your organization’s privacy and access policies.
Data migration helps authorized admins guide supported customer information into the white-label service.
White-label settings control the customer-facing brand, domain, and service experience.
## Where to go next
Go from an empty workspace to a browser test call.
Understand prompts, flows, testing, and publishing.
Plan compliant outbound conversations.
Let assistants offer and confirm available appointments.
# Quickstart
Source: https://docs.famulor.io/quickstart
Create your first assistant and test it with a web call
This guide takes you from an empty account to a live conversation with your own AI assistant — no phone number required for the first test.
New to Famulor? [Core concepts](/#core-concepts) on the Overview page, and the full [Glossary](/glossary), cover terms like Assistant, Flow, Campaign, and Phone number used throughout this guide.
## 1. Create an assistant
The **Create assistant** modal opens. Enter a name your team will recognize, e.g. `Reception EN`.
* **Single prompt** — free-form conversations from one system prompt (best for most first assistants).
* **Conversational flow** — visual flow builder for branches, data collection, and transfers.
Use **Build from scratch**, or apply a catalog template (filter by theme). Templates copy into the system prompt and optional first message — they are not live-linked.
In the editor:
* **Prompt mode:** greeting + system prompt on the canvas. Use **Choose template** anytime.
* **Flow mode:** open the flow builder; the base instructions live under Settings → General → **Advanced prompt** (also collapsed on the canvas).
A solid starting prompt:
```text theme={null}
You are Anna, the friendly phone assistant of Example GmbH.
You answer questions about opening hours, services, and pricing.
Keep answers short and conversational — you are on a phone call.
If the caller wants an appointment, collect their name and phone
number and confirm you will call back. Never invent information.
```
The defaults (a low-latency pipeline with a recommended voice) work well out of the box. You can browse the [voice library](/assistants/models-and-voices) later and preview voices before switching.
Your assistant is now ready to take calls.
## 2. Test it in the browser
Every test runs your assistant exactly as saved — same prompt, flow, tools, and knowledge base. Select the **Test** button in the editor header and pick how you want to test:
* **Chat** — a text-only session, no audio. The fastest way to get wording and logic right without speaking out loud.
* **Web Call** — a live voice call in the browser, no phone number involved:
1. Allow microphone access.
2. Talk to your assistant. Interrupt it mid-sentence — it should stop and listen.
3. End the call, then open **[History](/monitoring/history)** to review the transcript.
* **Call** — a real phone call, available once the assistant has an outbound number or a verified caller ID (step 3). Enter your own number and the assistant rings you.
* **Simulations** — an AI-played caller works through a scenario you define and scores the result; see [Simulations](/assistants/simulations).
A good progression: **Chat** first to settle the wording and logic, **Web Call** to hear timing and interruptions, then a real **Call** before you go live.
Web and phone test calls consume voice-time credits like any other call. A Chat test places no call. See [How usage is billed](/billing/minutes).
Iterate on the prompt between test calls. Short prompts with concrete rules ("keep answers under two sentences", "always confirm the phone number by reading it back") beat long essays.
## 3. Put it on a phone number
Chat and Web Call already run the assistant's real logic — once both sound right, move to an actual number:
* **Buy a number** in [Phone numbers](/telephony/phone-numbers) and assign the assistant to it — inbound calls are answered immediately.
* Or **connect your own SIP trunk** ([BYO SIP](/telephony/sip-trunks)) to use existing numbers.
* Or **verify a number you already own** as an outbound [caller ID](/telephony/caller-id) — enough for the **Call** test and for outbound calling, though it does not receive calls.
With an outbound number in place, use the editor's **Call** test to ring your own phone — the same telephony path a live call uses. For volume, set up a [campaign](/campaigns/overview); see [Inbound & outbound calls](/telephony/inbound-outbound) for how calls reach and leave an assistant.
## Next steps
When a single prompt is enough — and when to switch to a visual flow.
Background audio, interruption handling, filler phrases, guardrails.
Let the assistant answer from your documents.
Pipeline, realtime, and half-cascade explained.
# Audit log
Source: https://docs.famulor.io/settings/audit-log
See who changed what across your workspace, and when
The audit log is your workspace's own change record: what was changed, who changed it, and when. It is the page to open when a compliance review asks how a setting came to be the way it is, or when something in the workspace stopped behaving as expected.
Find it under **Settings → Data → Audit Log**. Workspace owners and admins can view recorded support access and changes made during support sessions on every plan. A plan that includes **Audit Log** also shows other workspace activity. Without that feature, support entries remain visible alongside an upgrade link to **Settings → Plan**.
## What it records
Entries are written as changes happen, across assistants and their tools, automations and campaigns, audience and knowledge-base content, telephony (numbers, SIP trunks, carrier connections, caller IDs), channels and email addresses, workspace settings such as [retention](/settings/data-retention) and [dark windows](/settings/dark-windows), and security actions — API keys created or revoked, members invited or removed, roles changed.
Each row names the person who acted, or **API / System** when the change came from a key or an automatic process rather than someone signed in, together with the action, the resource it touched, and the time. Newest entries sit on top. Use the page controls at the bottom to move between pages — each page loads a fresh set of entries.
## Search and sort
Type in the search box to keep only the entries matching an action, a resource, or the name or email of whoever made the change. Select the **Action** or **Time** column header to sort by it, and select it again to reverse the direction.
## Reading an entry
Select a row to expand it. A change to existing settings lists each field that changed with its before and after value side by side; other entries show whatever detail was recorded with them.
Recorded support sessions include the person accessing the workspace, the reason for access, and the session start. Leaving the session adds an end entry. Changes made during the session show the administrator who performed them and share the same access reason and session reference, so you can follow the work across entries. Expand a change to see the recorded fields or before-and-after values.
The impersonation marker identifies actions performed through a support session. Both recording this support activity and viewing its entries are available independently of the workspace's plan. The owner or admin role is still required to view them.
## See also
[Trust Center](/support/trust-center) and [Roles and team management](/settings/workspaces#roles-and-team-management).
# Consent & compliance
Source: https://docs.famulor.io/settings/consent-compliance
Choose universal or per-channel opt-outs and manage cross-channel suppression records.
Consent & Compliance controls how **marketing opt-outs** are enforced across a
workspace. Suppression enforcement is always active. Workspace owners and
admins configure the mode under **Settings → Data → Suppression**; other
members have read-only access.
## Consent modes
### Universal opt-out
An opt-out received on any channel blocks marketing outreach to the linked contact on voice, SMS, email, and supported messaging channels.
Universal mode is the conservative default and remains available on every
plan.
### Per-channel opt-out
An opt-out applies only to the originating channel. For example, an SMS
opt-out blocks SMS marketing while independent voice or email consent can
remain usable.
Per-channel mode requires the **Consent & Compliance** plan feature. If that
feature is unavailable, the workspace remains in universal mode; suppression
enforcement is never disabled.
Changing the workspace mode does not rewrite earlier opt-outs. The rule that applied when the contact opted out remains visible in the audit history.
## Suppression records
An active record can be linked to a contact, phone number, or email address. It shows the affected channels, where the request was received, its reason, and when it was created.
Listing with a `channel` filter returns both that channel's records and
universal (`all`) records, because both block outreach on the requested
channel.
## Restoring consent
Restoring consent does not erase compliance history. The active suppression is
revoked and an opt-in event is appended to the audit trail.
Use the suppression record ID whenever possible. The API also accepts a URL-encoded E.164 phone number or email address.
Only restore consent when you have an appropriate, documented basis to do so.
Product settings assist with enforcement but do not replace legal review for
your jurisdiction, outreach purpose, and communication channel.
## Legal grounding for outreach
This section is general information, not legal advice. Marketing and telemarketing rules vary by country and channel — confirm your specific case with legal counsel before launching a campaign.
Voice, SMS, and email outreach are regulated wherever you call or message into, not just where your workspace is based. A few frameworks come up most often:
| Region | Key rules |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| European Union | GDPR: a lawful basis for processing (Art. 6), valid consent conditions (Art. 7), and information duties toward the person you're contacting (Art. 13/14). |
| Germany | UWG §7 — unsolicited phone/email advertising is tightly restricted for consumers, and for businesses requires "presumed interest." |
| Austria | TKG 2021 §107 — unsolicited calls and messages generally need prior consent, including for business contacts. |
| Switzerland | nDSG, plus the star-registration ("Robinson list") opt-out for marketing calls. |
| United States | TCPA and CAN-SPAM — the reason **Universal Opt-Out** (above) is the recommended default: an opt-out on any channel suppresses all of them. |
Practical baseline regardless of region: keep a documented basis for each contact (consent record, existing relationship, or legitimate interest), make opting out easy and immediate, and keep the audit trail suppression records already provide. Pair this with your workspace's [data retention](/settings/data-retention) settings so contact and consent records aren't kept longer than needed. For outbound calling specifically, see [Dialer, retries & compliance](/campaigns/dialer-and-compliance).
## AI disclosure requirement
Since August 2026, the **EU AI Act's transparency obligation (Art. 50)** requires that people be told when they're interacting with AI — for example an AI voice assistant on a call — unless it's obvious from context. A short, clear line is enough, such as telling the caller up front that they're speaking with an AI assistant.
For workspaces whose AI inference region is **EU**, Famulor reviews this automatically after an assistant is saved. Consent wording, the effective greeting, and the opening prompt are assessed together. One clear AI introduction in any of those active sources is sufficient; the disclosure does not need to be repeated in every source. Uploaded audio greetings are checked from their transcription. A missing disclosure blocks the assistant until the opening is corrected or approved through compliance review.
The simplest way to comply is to have your assistant say so as part of its opening — see [Prompt writing](/assistants/prompt-writing) for structuring an assistant's greeting. If your assistant uses a **cloned voice**, a related but separate labelling duty also applies — see [Voice cloning consent](/assistants/voice-cloning-consent).
## REST API
Read or update the workspace mode:
```bash theme={null}
curl https://YOUR_DOMAIN/api/v1/settings/consent-compliance \
-H "Authorization: Bearer fam_..."
```
```bash theme={null}
curl -X PATCH https://YOUR_DOMAIN/api/v1/settings/consent-compliance \
-H "Authorization: Bearer fam_..." \
-H "Content-Type: application/json" \
-d '{"mode":"per_channel"}'
```
Record an opt-out:
```bash theme={null}
curl -X POST https://YOUR_DOMAIN/api/v1/suppression-list \
-H "Authorization: Bearer fam_..." \
-H "Content-Type: application/json" \
-d '{
"email": "contact@example.com",
"channel": "email",
"reason": "Unsubscribe request"
}'
```
The suppression API accepts at least one of `contact_id`, `phone`, or `email`.
When `channel` is omitted, phone defaults to `voice` and email defaults to
`email`. Use `GET /api/v1/suppression-list?channel=sms` to list records that
block SMS. Restore one record with
`DELETE /api/v1/suppression-list/{id-or-identity}`.
REST scopes are `settings:read` / `settings:write` for the mode and
`suppression:read` / `suppression:write` for records.
## MCP
* `get_consent_mode` and `set_consent_mode`;
* `list_suppression_entries`;
* `add_suppression_entry`;
* `remove_suppression_entry` (restores consent and retains the audit trail).
MCP follows the same permissions and returns the same customer-facing data as the REST API.
# Dark Windows
Source: https://docs.famulor.io/settings/dark-windows
Pause proactive outbound activity per channel during quiet hours.
Dark Windows are available under **Settings → Data → Dark Windows**. They let
workspace owners and admins pause proactive outbound activity for individual
channels without turning the channel off.
## How a window works
Each channel has its own on/off switch, start time, and end time. Times use the
workspace timezone shown on the page. The start is included and the end is
excluded. A window such as `21:00` to `08:00` runs overnight.
Dark Windows apply to proactive sends and dials from
[campaigns](/campaigns/overview), callbacks,
[automations](/automations/overview), the API, and MCP. Replies to inbound
customer messages and manual replies from [History](/monitoring/history)
remain available.
## Channels
You can configure separate windows for Voice, SMS, Email, WhatsApp, Telegram,
Slack, Messenger, Microsoft Teams, Discord, Google Chat, and X.
Workspaces that opt into beta features also see separate controls for
Freshdesk, Gmail, Outlook, Zendesk, ServiceNow, Intercom, Zoho Mail, AgentMail,
Instagram, and Zulip. The generic Email window and the provider-specific email
windows are independent.
## API and MCP
* `GET /api/v1/settings/dark-windows` returns all channel windows and the
workspace timezone.
* `PATCH /api/v1/settings/dark-windows` updates one or more channels. Channels
omitted from `settings` remain unchanged.
* MCP tools: `get_dark_window_settings` and `update_dark_window_settings`.
REST uses `settings:read` / `settings:write`; MCP also accepts the matching
assistant read/write scopes.
```json theme={null}
{
"settings": {
"gmail": { "enabled": true, "start": "21:00", "end": "08:00" },
"outlook": { "enabled": true, "start": "22:00", "end": "07:00" }
}
}
```
# Data retention
Source: https://docs.famulor.io/settings/data-retention
Control how long each workspace data channel is kept.
Data retention controls how long your workspace keeps calls, recordings,
transcripts, messages, and campaign leads before they are deleted
automatically. It is available under **Settings → Data Retention** when the
workspace plan includes the **Data Retention** feature. If the feature is not
included, the page links to **Settings → Plan** for an upgrade.
## Default and channel overrides
The plan default is **24 months (720 days)** unless the governing plan defines
a different period. Leaving a channel without a custom value keeps that plan
default; the workspace is not silently populated with an override.
Workspace owners and admins can set a retention period for:
* calls, including voice, AI avatar, live chat and WhatsApp voice history;
* call recordings, transcripts, summaries and caller-memory data;
* campaign leads;
* email threads and the outbound SMS log;
* Telegram, Slack, Messenger, Microsoft Teams, Discord, Google Chat, X and
WhatsApp conversations, messages and stored media.
Active campaign leads are protected. Email retention evaluates the last
activity of the entire thread, so an old root message with a recent reply is
not deleted.
## Which plan applies?
A workspace on the main platform follows its platform plan. A customer
workspace created through a white-label reseller follows the plan in that
reseller's catalog. The same rule applies to free-account defaults and
retention limits.
## Deletion and audit trail
Expired data is removed automatically. Deletions are recorded in an audit trail to support your retention and compliance reviews — see [Trust Center](/support/trust-center) for the platform's broader data-protection commitments. If configurable retention is not included in the plan, workspace-specific cleanup settings do not apply.
## Legal basis
This section is general information, not legal advice. Confirm applicable retention rules with legal counsel for your industry and jurisdiction.
Automatic deletion supports the GDPR's storage-limitation principle (Art. 5(1)(e)): personal data should not be kept longer than necessary for the purpose it was collected for. The **right to erasure** (Art. 17) and the **record of processing activities** (Art. 30) that many businesses must maintain both depend on knowing — and being able to show — how long each type of data is actually kept.
A shorter deletion window is not always safer. Statutory retention **minimums** — commercial records, tax-relevant documents, medical records, and personnel files, among others — can require keeping specific data for years even after your normal retention period would delete it. Check whether any of your call or message content falls under such an obligation before shortening a retention period, and route anything that does through your own archiving process outside Famulor.
## API and MCP
* `GET /api/v1/settings/retention` reads the current default, channel settings, and allowed range.
* `PATCH /api/v1/settings/retention` updates one or more channel values. Send
`null` to clear an override and restore the plan default.
* MCP tools: `get_retention_settings` and `update_retention_settings`.
REST uses `settings:read` / `settings:write`; MCP also accepts the matching
assistant read/write scopes.
# Migrate from Famulor 1.0
Source: https://docs.famulor.io/settings/famulor-migration
Preview and import supported assistants, tools, knowledge, campaigns, automations, and BYO telephony
Open **Settings → Workspace → Data migration** to move supported resources from a Famulor 1.0 account into the current workspace. Only copies are created — nothing is deleted from the old account, and it keeps working while you set things up here.
Moving from Retell AI, Vapi, or Synthflow instead? The same panel handles those — see [Migrate from Retell AI, Vapi, or Synthflow](/settings/provider-migrations).
## Recommended workflow
Choose **Connect with my Famulor 1.0 account**, or paste a Famulor 1.0 API key into the field below it. Either way the credential is used only for this run and is never saved. Do not paste credentials into the Milian conversation.
Load a preview to see the available resources, compatibility notes, and items that need manual follow-up.
Choose the assistants, reusable tools, knowledge-base structure, campaigns, automations, and supported BYO telephony connections you want to import.
Start the import, then open each imported resource and complete the review checklist before using it with customers.
## What to expect
* **Assistants** keep supported prompts, greetings, voice settings, variables, flows, and compatible tool links.
* **Reusable tools** are imported without exposing saved credentials. Re-enter any secret required by the destination connection.
* **Knowledge bases** arrive as empty containers with their names and assistant links. Document **content cannot be transferred** — Famulor 1.0 never hands out the files themselves, so every document is listed as skipped in the import report and has to be uploaded again by hand. Website and cloud-drive sources need reconnecting too.
* **Campaigns** are created as drafts. Review the audience, sender, schedule, retries, and calling window before starting them.
* **Automations** are created as disabled drafts. Review every trigger, action, and app connection before enabling them.
* **BYO telephony** can be recreated when the source provides enough customer-owned connection information. Follow the setup shown in the destination workspace before routing live traffic.
The preview highlights unsupported or incomplete items rather than silently enabling them.
## Items that often need manual work
* marketplace or rented phone numbers tied to the old account;
* knowledge documents that must be uploaded or connected again;
* campaign audiences and channel-specific senders;
* external calendar, email, CRM, and automation app authorizations;
* older flow steps or tool types that do not have a direct equivalent;
* how assistants are organized — Famulor 1.0's folders and labels have no counterpart here, so the import skips them. Assistants live in one list and are grouped with **tags** instead.
Imported campaigns and automations stay inactive until you explicitly approve them. This prevents an import from contacting customers or running external actions unexpectedly.
Enter the Famulor 1.0 API key only in the migration dialog itself. Never paste an API key or other secret into a Milian conversation.
## REST API and MCP
Use `POST /api/v1/migrations/famulor` with `action: "preview"` before sending `action: "import"` with the selected source IDs. The credential needs read permission for the preview and the matching write scopes for the resources you import.
The same workflow is available through the MCP tools `preview_famulor_1_migration` and `import_famulor_1_data`.
# Marketing integrations
Source: https://docs.famulor.io/settings/marketing
Configure GA4, Meta, Google Ads and Microsoft UET on a white-label domain.
Marketing integrations add analytics and advertising tags to a [**verified white-label domain**](/admin/tenants-and-whitelabel). The reseller controls the configuration for that domain; customer workspaces do not configure separate tags.
## Where to configure
Open **Tenant Admin → Settings → Marketing** on the white-label workspace.
Use **Custom scripts** only for tags that are not covered by the guided fields. Connection tokens are saved securely and are not displayed again after saving.
## Events
| Event | When | Ads primary |
| ---------------- | --------------------------------------------------- | --------------- |
| `generate_lead` | Demo / enterprise / ROI forms on the marketing site | Yes |
| `sign_up` | Successful registration | Yes |
| `begin_checkout` | Plan checkout started | No |
| `purchase` | Paid Stripe checkout | Yes (EUR value) |
Browser and conversion events are coordinated to avoid reporting the same conversion twice.
## API and MCP
* `GET /api/v1/settings/marketing` / `PUT /api/v1/settings/marketing`
* MCP `get_marketing_integrations` / `update_marketing_integrations`
Requires white-label access and `settings:read` / `settings:write`.
# Migrate from Retell AI, Vapi, or Synthflow
Source: https://docs.famulor.io/settings/provider-migrations
Preview which assistants and settings are copied, then import them into your Famulor workspace.
Open **Settings → Workspace → Data migration** and choose Famulor 1.0, Retell AI, Vapi, or Synthflow.
Famulor 1.0 copies supported assistants, tools, knowledge, campaigns, automations, and BYO telephony into this workspace. See [Migrate from Famulor 1.0](/settings/famulor-migration).
The migration first shows a preview. You choose the assistants to copy before Famulor creates anything. Imported assistants are inactive, so you can review and test them before they handle conversations.
## What is copied
* Assistant name
* System prompt and portable text greeting
* Primary language
* Compatible conversation settings such as temperature, voice speed, call duration, timezone, and recording preference when the source provides them
Famulor uses workspace-approved model and voice defaults during this first stage. Choose and preview the final voice in each imported assistant.
## What needs review
Tools, actions, knowledge content, conversation flows, squads and handoffs, phone numbers, routing, widgets, and credentials are not silently recreated. The preview lists the relevant follow-up work for every assistant.
Never paste a provider key into Milian or another chat. Enter it only in the password field inside the authenticated migration dialog. The key is used for the current preview or import request and is not saved.
Your source account stays unchanged. Route calls to Famulor only after you have reconnected dependencies, selected a voice, and completed a test conversation.
For programmatic migrations, see [Preview or import provider assistants](/api-reference/migrate-provider-assistants).
# Workspaces
Source: https://docs.famulor.io/settings/workspaces
Switch workspaces, create additional ones, and manage each workspace's profile and team
A **workspace** keeps its assistants, calls, campaigns, knowledge, phone numbers, plan, credits, and billing separate. Signing up creates your first workspace automatically.
You can also join other workspaces and, when your plan allows it, create additional workspaces of your own.
## Switching workspaces
Select the workspace avatar at the top of the sidebar. The switcher lists every workspace you can access and your role in each one. Choosing a workspace reloads the dashboard with that workspace's data.
Your selection affects only your own session. Other members keep their current workspace.
## Creating another workspace
Open the workspace switcher and choose **New workspace**. The dialog shows whether your account can create another workspace and prompts you to choose a name.
The number of additional workspaces depends on your plan and the **Extra Workspaces** add-on — extra capacity bought per additional workspace from **Settings → Plan**, the same way the other capacity add-ons work. Joining someone else's workspace does not consume your creation allowance. Existing workspaces remain accessible if your allowance later changes; the limit applies when creating a new one.
Each new workspace starts separately, so review its plan and billing before adding production resources.
## Workspace profile
Open **Settings → Workspace** to view and edit the active workspace's identity and defaults: its logo, name, company website, timezone, date format, country, and the default language for members who haven't chosen one themselves. Owners and admins can change these fields; every other role sees the same fields read-only. A new workspace detects its country from the signup or first-use location; an owner or admin can replace that choice at any time. The page also shows the workspace ID — read-only, and the value to quote in [support requests](/support) and API calls.
When your billing profile has no address yet, the workspace country is used as the initial billing country for checkout. Existing billing addresses are preserved. Review and complete the billing address during checkout; changing the workspace country does not replace an address already saved in your billing profile.
**AI inference region** controls where Famulor runs the AI processing behind this workspace — the language-model work in conversations and the AI judge that analyses them afterwards. **Global** lets Famulor's own routing choose; pinning **EU** or **US** keeps that processing inside the chosen zone and narrows the model catalog to what is offered there, so an assistant can only be set to a model available in the region. This is the workspace-level control behind the processing-location commitments described in [Trust Center](/support/trust-center). Pinning either region can raise the cost of that AI usage compared with Global routing.
Selecting **EU** also activates an after-save AI-disclosure review for every assistant. The review checks the consent announcement, the effective opening greeting (including an uploaded audio greeting or caller-first silence path), and opening prompt instructions. At least one effective opening path must clearly tell the caller that they are interacting with an AI assistant. Changing the region re-reviews existing assistants.
The **Beta features** toggle also lives on this page. Several capabilities referenced elsewhere in these docs — connected-app triggers in [Automations](/automations/overview), [WhatsApp Call](/telephony/whatsapp-voice), and the Beta channel connectors, among others — stay hidden until an owner or admin turns it on. Beta features can be unstable and change, and some process additional conversation context and add AI usage, so review each one before enabling it.
## Roles and team management
Open **Settings → Workspace → Team** in the workspace where the person should work. Invitations and roles apply only to that workspace, and a person can hold a different role in each workspace they belong to — owner in one, member or viewer in another. The Team panel always shows the active workspace's name to help prevent inviting someone into the wrong account.
### Roles
| Role | Access |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **owner** | Full access, including team, billing, and workspace settings. The account that created the workspace holds this role; it can't be handed to anyone else, changed, or removed from the Team panel. |
| **admin** | Full access, including team, billing, and workspace settings. |
| **member** | Full access to the workspace features assigned to them. |
| **viewer** | Read-only — can't make any changes. |
| **billing** | Read-only, plus managing Plan and Balance. The sidebar shrinks to the dashboard, Usage, and a Settings page reduced to Preferences, Plan, and Balance. |
### Inviting a member
Owners and admins add a member one of two ways:
* **Invite by email** — sends an email with a link to set a password. An existing account is added directly and notified by email instead of getting an invite link.
* **Create with a password** — set a name and an initial password (at least 8 characters) yourself, with no email round-trip.
Both modes ask for the new member's role up front — any role except owner — and show that role's description as you pick it. A member added by email keeps an **Invited** badge in the list until they sign in for the first time. Once a workspace reaches its member limit, **Invite member** is replaced by a link to **Settings → Plan** for more capacity.
### Managing a member
From a member's row, owners and admins can:
* **Change their role** — pick a new one from the dropdown; it applies immediately.
* **Send a login link** — emails a single-use link that signs the member in without a password and expires shortly after, useful when someone is locked out.
* **Remove them** — drops their access to this workspace only, without affecting any other workspace they belong to, and leaves their Famulor account itself intact.
The owner's row carries none of these controls; every other member can have their role changed or be removed.
## REST API
List the workspaces visible to the credential:
```bash theme={null}
curl https://YOUR_DOMAIN/api/v1/workspaces \
-H "Authorization: Bearer fam_..."
```
Create a workspace with a user-authorised credential:
```bash theme={null}
curl -X POST https://YOUR_DOMAIN/api/v1/workspaces \
-H "Authorization: Bearer fam_..." \
-H "Content-Type: application/json" \
-d '{"name":"Acme Corp — EU"}'
```
Use `settings:read` to list workspaces and `settings:write` to create one. A workspace-only service credential can list its own workspace but cannot create a workspace on behalf of a person.
Read or update the country of the workspace bound to the credential:
```bash theme={null}
curl https://YOUR_DOMAIN/api/v1/settings/workspace-country \
-H "Authorization: Bearer fam_..."
curl -X PATCH https://YOUR_DOMAIN/api/v1/settings/workspace-country \
-H "Authorization: Bearer fam_..." \
-H "Content-Type: application/json" \
-d '{"country_code":"DE"}'
```
Reading requires `settings:read`; changing it requires `settings:write`. Send `null` to return to automatic location detection on the next dashboard or sign-in request.
Create a dedicated API key for a workspace returned by the list endpoint:
```bash theme={null}
curl -X POST https://YOUR_DOMAIN/api/v1/workspaces/WORKSPACE_ID/api-keys \
-H "Authorization: Bearer fam_..." \
-H "Content-Type: application/json" \
-d '{
"name":"EU reporting",
"scopes":["calls:read","leads:read"],
"expires_in_days":90
}'
```
This operation requires a user-authorised credential with `settings:write`. The credential's user must currently be an owner or admin in the selected workspace, and the workspace must belong to the same brand as the credential. It works for regular multi-workspace accounts and does not require white-label access. Members, viewers, billing users, and workspace-only service credentials cannot use it.
The new key is permanently bound to the selected workspace. Its scopes cannot exceed the calling credential, and it cannot outlive a calling credential that already has an expiry. The plaintext key appears only in the successful response, so store it immediately and do not retry a successful request automatically. A newly created workspace may receive its key before plan activation, but normal API calls with that key remain plan-gated.
Workspace-capacity and extra-member add-ons have separate jobs: workspace capacity controls creating additional workspaces, while member capacity controls invitations. Neither adds another requirement after a user already has an owner/admin role in the target workspace.
## MCP
* `list_workspaces` lists the workspaces visible to the connected user.
* `create_workspace` creates a workspace when the connected user has remaining allowance.
* `create_workspace_api_key` creates a dedicated key for a visible workspace where the connected user is an owner or admin.
* `get_workspace_country` reads the active workspace country.
* `update_workspace_country` sets an ISO two-letter country code or returns to automatic detection.
These operations follow the same permissions and plan rules as the REST API. Inviting, removing, or changing a member's role has no REST or MCP equivalent — team management is UI-only.
# Support
Source: https://docs.famulor.io/support
How to reach the Famulor team, what to include in a request, and enterprise support options
We're glad to help with setup questions, bug reports, and feature requests.
## Support options
### Send from Milian
Direct Famulor workspaces can ask Milian to create a support request. Milian prepares an
editable card with **Subject** and **Message**; nothing is sent until you click **Send
request**. After submission, keep the displayed `SUP-…` reference for follow-up.
This in-app option is not available in white-label or reseller-customer workspaces.
Never include passwords, access tokens, API keys, or payment-card data in the message.
### Email support
Email [support@famulor.io](mailto:support@famulor.io) with your request and the team will get back to you.
### Enterprise support
Dedicated support channels with SLA commitments and higher concurrency for high-volume calling are available on enterprise plans — see [Enterprise](/enterprise) for what's included and how to get started.
## What to include in a request
To speed up troubleshooting, include:
* Your workspace or account identifier
* The assistant ID, campaign ID, or phone number involved
* An approximate timestamp and timezone
* Expected behavior vs. actual behavior
* Relevant screenshots or API request/response samples
## Where to go next
Quick answers on getting started, telephony, pricing, and compliance.
Terms used across Famulor and voice AI in general.
Data sovereignty commitments, technical safeguards, and how to request a DPA.
Dedicated support, higher concurrency, and a hands-on rollout.
# Trust Center
Source: https://docs.famulor.io/support/trust-center
Transparency on Famulor's infrastructure, sub-processors, and technical safeguards
At Famulor, **data sovereignty** is a baseline requirement of modern AI communication. This Trust Center gives full transparency into our infrastructure, our specialized sub-processors, and the technical safeguards that protect sensitive data.
This page serves as a living annex to our Data Processing Addendum (DPA) and is updated regularly to match our current technology stack. Terms like LLM, STT, TTS, SIP trunk, or realtime model are explained in the [Glossary](/glossary).
## Infrastructure security
Every layer of our platform is built on security-first principles.
### Encryption
AES-256 encryption at rest, TLS 1.3 in transit. Voice data, transcripts, and customer information are encrypted end-to-end across the full call lifecycle.
### Access control
Role-based access control (RBAC) and least-privilege principles across all systems. Every access is logged and auditable.
### Monitoring & detection
24/7 security monitoring with intrusion-detection systems, anomaly alerting, and comprehensive audit logging for all system activity.
### Business continuity
Automated backups, disaster-recovery procedures, and a 99.9% availability SLA. Redundant infrastructure across multiple availability zones.
### Incident response
A documented incident-response plan with defined escalation procedures, compliance with GDPR's 72-hour breach-notification requirement, and post-incident review.
### Sub-processor security
Every AI sub-processor is reviewed for security and compliance before it's added to the platform. Native, EU-resident plugins are used wherever available for the highest-sensitivity workloads (see [Speech services](#5-speech-services-stt--tts) below).
## 1. Our sovereignty commitments
To meet the strict requirements of the European market — including GDPR Art. 9 for healthcare and other sensitive-data use cases — we operate on four principles:
| Principle | Description |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **EEA-first policy** | Core processing of voice and text data runs on servers within the European Economic Area (EEA), hosted out of Frankfurt, Germany. |
| **No-training guarantee** | We contractually ensure that none of our AI providers may use your data (audio, transcripts, or prompts) to train or improve their base models. |
| **Minimization by default** | [Retention](/settings/data-retention) is configurable per data channel, down to as little as one month, with automatic deletion once a record expires. |
| **Encryption everywhere** | All data is encrypted in transit with TLS 1.2+ and at rest with AES-256. |
An earlier version of this page described a "Zero Retention Mode" that processed data purely in memory. That specific mode is not part of the current platform — minimization today works through the configurable retention windows above, down to one month. If your organization needs a stricter guarantee, contact [support@famulor.io](mailto:support@famulor.io).
### AI inference region (workspace setting)
Under **Settings → Workspace**, the **AI inference region** setting controls which region provider inference runs in for a workspace's AI: **Global**, **EU**, or **US**.
This setting affects both the provider/model selection shown in the dashboard (UI) and in the API — only the offering actually available in the selected region is shown.
* **EU:** only EU providers and models are shown and used for processing.
* **US:** only US providers and models are shown and used.
* **Global:** the Famulor proxy routes dynamically based on the user's location and provider availability.
Which specific providers/models this affects can change as new models are released — the region control itself, via this workspace setting, stays in place. The sections below show, per provider, where EU and/or US processing is available.
## 2. System status & availability
Transparency about system performance matters to us. You can check live status at any time:
**Live status:** [https://status.famulor.io/](https://status.famulor.io/)
## 3. Infrastructure & platform hosting
These providers host the Famulor platform, including backend logic, databases, and the customer dashboard.
| Provider | Purpose | Processing location |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Vercel Inc. | Application hosting, frontend, and edge functions | Frankfurt, Germany (EU) |
| Supabase | Database, authentication, and file storage | EU (Central EU, Frankfurt) |
| LiveKit Inc. | Realtime infrastructure for virtual conversation rooms (realtime sessions) and, for most providers in section 5, the default routing path to their models | EU-SCC with region pinning (per the provider, data does not leave the European region); workspaces with AI inference region **US** additionally get US worker infrastructure (see [AI inference region](#ai-inference-region-workspace-setting)) |
| Amazon Web Services (AWS) | Object/file storage (e.g. recordings, assets) | EU region Frankfurt (`eu-central-1`) by default |
## 4. Artificial intelligence (LLM)
These models handle reasoning and conversation logic. Model access is routed through an AI gateway with enterprise-grade data handling; native, direct connections are used for select providers where EU data residency requires it.
**Note:** The LLM provider is set automatically by the platform for most workspaces (see the standard table below) and is not manually selectable. Only workspaces with the **Fallbacks & Guardrails** add-on ("Automatic model fallback chains plus configurable guardrails for production reliability") can choose the provider per assistant and configure additional fallback chains.
Standard (without the Fallbacks & Guardrails add-on):
| Provider | Model / service | Processing location |
| ------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Microsoft Ireland (Azure) | OpenAI models | EU regions (Sweden Central) / US, depending on the [AI inference region](#ai-inference-region-workspace-setting) workspace setting |
| Google Cloud (Vertex AI) | Gemini models, and **Gemma** (Google's open-source model family) for select Pipeline-mode configurations | EU regions (EU Data Residency) / US, depending on the [AI inference region](#ai-inference-region-workspace-setting) workspace setting |
Additionally selectable with the Fallbacks & Guardrails add-on:
| Provider | Model / service | Processing location |
| -------------- | -------------------------------------------------- | -------------------------------------------------------------------------- |
| Anthropic, PBC | Claude models (via EU-resident routing) | EU regions |
| Groq, Inc. | High-speed inference for select open-weight models | Verify current region with [support@famulor.io](mailto:support@famulor.io) |
## 5. Speech services (STT & TTS)
Specialized providers for real-time transcription (speech-to-text) and speech synthesis (text-to-speech). Famulor's engine-mode architecture (Pipeline / Realtime / Half-Cascade) determines which of these run for a given assistant. The realtime infrastructure (LiveKit) and the object storage (AWS) behind it are listed in [section 3](#3-infrastructure--platform-hosting).
**Note:** The **STT provider (transcription)** — like the LLM — is set automatically by the platform and is not manually selectable without the **Fallbacks & Guardrails** add-on. The **TTS provider (voice synthesis, voice selection)** can be chosen by any user regardless of the add-on — only the voices/providers available in the workspace region selected under [AI inference region](#ai-inference-region-workspace-setting) are shown. SIP trunk providers are selectable per assistant, depending on the use case.
| Provider | Category | Service / purpose | Processing location |
| ----------------------------------------------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Deepgram, Inc.](https://deepgram.com/learn/deepgram-eu-endpoint-now-generally-available) | STT / TTS | Real-time transcription (Nova) and voice synthesis (Aura) | EU endpoint available (`api.eu.deepgram.com`); GDPR-compliant EU-region usage. |
| [Soniox, Inc.](https://soniox.com/docs/stt/security-and-privacy) | STT / TTS | High-accuracy transcription (native EU-resident plugin); voice synthesis (added 2026-09-02) | STT: EU region (`stt-rt.eu.soniox.com`), contractually restricted to EU nodes. TTS: EU access for this product was confirmed by Soniox on 2026-09-02 and is being rolled out; until then, TTS calls are temporarily processed on Soniox's US region regardless of workspace setting. |
| [Gladia SAS](https://gladia.io/compliance-hub) | STT | Real-time and batch speech-to-text, native EU-resident plugin | EU region (`eu-west`); EU and US workloads processed separately. |
| [ElevenLabs Inc.](https://elevenlabs.io/docs/overview/administration/data-residency) | TTS | Voice synthesis models | EU Data Residency (Enterprise) and EU endpoints available. |
| [Cartesia AI, Inc.](https://cartesia.ai/blog/gdpr-compliance) | TTS | Ultra-low-latency voice synthesis (Sonic) | GDPR-compliant per provider; EU region usable. |
| [Fish Audio](https://fish.audio/) | TTS | Voice synthesis | US only |
| [xAI](https://x.ai/) | TTS | Voice synthesis | US only |
| Microsoft Ireland (Azure) | STT / TTS | Azure Speech (native plugin, mandatory for this provider option) | EU regions; data stays in the region of the created resource. |
| Google Cloud (Vertex AI) | STT / TTS | Speech-to-Text and Text-to-Speech | EU regions (Vertex AI EU Data Residency). |
| [AssemblyAI](https://www.assemblyai.com/) | STT | Transcription | US only |
| [Speechmatics](https://www.speechmatics.com/) | STT | Transcription | US only |
| [Inworld AI](https://inworld.ai/security) | TTS | Voice synthesis | Global / EU / US (subject to the selected workspace region and provider availability). |
| [Rime AI](https://rime.ai/) | TTS | Voice synthesis | US only |
| [Krisp Technologies](https://krisp.ai/) | Noise cancellation | Background-noise removal on live calls | Local processing: AI-based noise cancellation runs directly within the processing pipeline (on the respective server), not in a separate Krisp cloud. Per [Krisp's security controls](https://trust.krisp.ai/controls), no audio data is sent to Krisp when noise cancellation alone is used. |
Not every provider listed above processes every call. Famulor selects EU-resident, native connections for higher-sensitivity workloads (Soniox, Gladia, Azure) and uses a managed inference path for the rest — both are covered by the transfer safeguards in [section 10](#10-international-data-transfers--safeguards).
## 6. Business operations & billing
Providers for transactional security and administrative management.
| Provider | Purpose | Processing location |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Stripe Payments Europe | Secure payment processing (platform billing; customers may also connect their own Stripe account) | Ireland (EU) |
| Twilio Ireland Limited | Telephony, SIP trunking, and SMS | Ireland (EU). Regional processing via Twilio Regions (including IE1); US1 also available, depending on workspace configuration. |
| SendGrid (Twilio) | Transactional and system email, and the email conversation channel | EU regions (EU Data Processing Locations) |
| Meta Platforms Ireland Limited | WhatsApp Business Platform (Cloud API) — connected directly, not routed through Twilio | EEA, per Meta's Business Tools Terms |
| Composio | Brokers OAuth connections only for app connectors marked **Beta** in the Agent Connectors / App Catalog — only active for the specific beta apps a workspace connects. Established native integrations (e.g. HubSpot, Salesforce) connect directly, not via Composio; there, the user can choose whether to connect to that provider's EU or US API endpoint. | Global |
## 7. WhatsApp Business processing
For WhatsApp Business:
* The integration connects directly to **Meta's WhatsApp Cloud API** — not routed through Twilio.
* You can use either your **own WhatsApp-enabled number** or a number from the **Famulor number pool** (depending on setup/verification).
* If using your **own number**, the number owner must complete verification directly in **Meta Business Manager**.
* Inbound WhatsApp messages are processed through configurable **LLM workflows**.
* Replies are sent back as an **AI-generated message**.
* **Text, images, and voice messages** can be processed within the enabled assistant configuration and used for reply generation.
## 8. Platform analytics
For product analytics on the dashboard itself, Famulor uses:
| Provider | Purpose | Note |
| -------- | ----------------------- | ------------------------------------ |
| PostHog | Product usage analytics | EU Cloud region (`eu.i.posthog.com`) |
Famulor's documentation site (docs.famulor.io) separately uses Google Analytics 4 and Microsoft Clarity for content analytics — these do not process data from your workspace or calls. White-label customers may optionally connect their own Google Tag Manager, GA4, or Meta Pixel to their own branded domain; that configuration and its data are the customer's own.
## 9. Provider legal entities & addresses
The legal entity behind each provider, with a publicly available business address (as of the date below). Newer providers added since our last full review are marked — contact [support@famulor.io](mailto:support@famulor.io) for their current entity details pending the next quarterly update.
| Provider | Legal entity | Address | Source |
| --------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| Vercel | Vercel Inc. | 440 N Barranca Ave #4133, Covina, CA 91723, USA | [Vercel Terms](https://vercel.com/legal/terms) |
| Supabase | Supabase Pte. Ltd. | 65 Chulia Street #38-02/03, OCBC Centre, Singapore 049513 | [Supabase Terms](https://supabase.com/terms) |
| Microsoft (Azure) | Microsoft Ireland Operations Limited | 70 Sir John Rogerson's Quay, Dublin 2, D02 R296, Ireland | [LEI Register](https://lei.info/549300WCLFVEBTBNRF76) |
| Google Cloud | Google Cloud EMEA Limited | 70 Sir John Rogerson's Quay, Dublin 2, Ireland | [Google Contracting Entity](https://cloud.google.com/terms/google-entity/index-20210816) |
| Anthropic | Anthropic, PBC | 548 Market Street, PMB 90375, San Francisco, CA 94104, USA | [OpenGov](https://opengovco.com/business/20241311617) |
| Groq | Groq LLC | P.O. Box 1778, Mountain View, CA 94042, USA (registered-agent address per ToS) | [Groq Terms of Use](https://groq.com/terms-of-use) |
| Soniox | Soniox, Inc. | 1045 Helm Ln, Foster City, CA 94404, USA (EU site: Cesta v Gorice 34B, 1000 Ljubljana, Slovenia) | [Soniox Contact](https://soniox.com/contact) |
| ElevenLabs | Eleven Labs Inc. | 169 Madison Ave #2484, New York, NY 10016, USA | [ElevenLabs Help](https://help.elevenlabs.io/hc/en-us/articles/21757104682001-What-is-your-billing-address-and-VAT-EIN-number) |
| Deepgram | Deepgram, Inc. | 548 Market St, Suite 25104, San Francisco, CA 94104-5401, USA | [EU Endpoint Announcement](https://deepgram.com/learn/deepgram-eu-endpoint-now-generally-available) |
| Gladia | GLADIA SAS | 6B, rue du Bas Village, 35510 Cesson-Sevigne, France | [Gladia Legal Notice](https://www.gladia.io/legal-notice) |
| Cartesia | Cartesia AI, Inc. | 1766 18th Street, Suite 1200, San Francisco, CA, USA | [Company info](https://www.crunchbase.com/organization/cartesia) |
| Fish Audio *(new)* | Shanghai Qita Dynamic Technology Co., Ltd | Room 1203J, No. 337 Shahe Road, Jiangqiao Town, Jiading District, Shanghai, China | [Fish Audio Terms](https://fishaudio.org/en/terms) |
| AssemblyAI *(new)* | AssemblyAI, Inc. | 169 Madison Ave STE 38365, New York, NY 10016, USA | [AssemblyAI Terms](https://www.assemblyai.com/legal/terms-of-service) |
| Speechmatics *(new)* | Cantab Research Ltd (trading as Speechmatics) | One Cambridge Square, Milton Avenue, Cambridge, CB4 0AE, United Kingdom | [Speechmatics Terms](https://www.speechmatics.com/legal/terms-of-service) |
| Inworld AI *(new)* | Theai, Inc. (d/b/a Inworld) | 1975 West El Camino Real, Suite 300, Mountain View, CA 94040, USA | [Inworld Terms](https://inworld.ai/terms) |
| Rime AI *(new)* | Rime Labs, Inc. | 911 Minna St, San Francisco, CA 94103, USA | [Rime Terms](https://rime.ai/terms) |
| Krisp *(new)* | Krisp Technologies, Inc. | 2150 Shattuck Ave, Penthouse 1300, Berkeley, CA 94704, USA | [Krisp Master Subscription Agreement](https://krisp.ai/master-subscription-agreement/) |
| Composio *(new)* | Sampark Inc (d/b/a Composio) | *Pending next review — Composio's own Terms/Privacy pages do not disclose a business address* | [Composio Terms](https://composio.dev/terms) |
| xAI *(new)* | SpaceXAI LLC (Nevada, USA) | *No street address disclosed in the ToS; EU representative under DSA Art. 13: EDSR, Valukoja 8/2, 2nd floor, 11415 Tallinn, Estonia* | [xAI Terms of Service](https://x.ai/legal/terms-of-service) |
| AWS *(new)* | Amazon Web Services EMEA SARL | 38 Avenue John F. Kennedy, L-1855 Luxembourg | [AWS EU Data Protection](https://aws.amazon.com/compliance/eu-data-protection/) |
| LiveKit | LiveKit Inc. | 4285 Payne Avenue, Suite 9154, San Jose, CA 95157, USA | — |
| Stripe | Stripe Payments Europe, Limited | One Wilton Park, Wilton Place, Dublin 2, D02 FX04, Ireland | [LEI Register](https://lei.info/549300DSKP4KJP52XY61) |
| Twilio | Twilio Ireland Limited | 70 Sir John Rogerson's Quay, Dublin 2, D02 R296, Ireland | [LEI Register](https://lei.info/635400HZOP3LBSUGAN82) |
| SendGrid (Twilio) | Twilio Ireland Limited | 70 Sir John Rogerson's Quay, Dublin 2, D02 R296, Ireland | [LEI Register](https://lei.info/635400HZOP3LBSUGAN82) |
| PostHog | PostHog, Inc. | 2261 Market St., #4008, San Francisco, CA 94114, USA | [PostHog DPA](https://posthog.com/dpa) |
| Meta (WhatsApp Business Platform) | Meta Platforms Ireland Limited | 4 Grand Canal Square, Grand Canal Harbour, Dublin 2, Ireland | [Meta Business Tools Terms](https://www.facebook.com/legal/technology_terms) |
## 10. International data transfers & safeguards
For providers with US parent companies (e.g. Microsoft, Google, Vercel, Groq, ElevenLabs, Deepgram, Cartesia, LiveKit, AWS), Famulor ensures compliance through:
* **Data residency:** configuring services so data is processed exclusively on EU nodes wherever the provider offers it.
* **Legal framework:** use of the EU-U.S. Data Privacy Framework (DPF) and/or Standard Contractual Clauses (SCCs).
* **Enterprise agreements:** contracts that exclude third-party access and model-training use of your data.
* **TIA on request:** for enterprise customers, Famulor prepares a Transfer Impact Assessment (TIA) on request, per EDPB Recommendations 01/2020, for any provider with a US parent company.
### Transfer legal basis per US-based provider
| Provider | Category | Transfer legal basis |
| ------------------------------------------------------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Deepgram | STT/TTS | SCCs (2021/914/EU) + EU endpoint (`api.eu.deepgram.com`) |
| Soniox | STT / TTS | SCCs + EU Data Residency for STT (contractually restricted to EU nodes); TTS temporarily processed under SCCs on Soniox's US region during EU rollout (see [section 5](#5-speech-services-stt--tts)) |
| Gladia | STT | SCCs (2021/914/EU), separate EU/US workloads |
| Cartesia | TTS | SCCs + EU Data Residency |
| LiveKit | Realtime | SCCs + region pinning (per provider, no processing outside the EU region) |
| ElevenLabs | TTS | Enterprise DPA + EU Data Residency |
| Vercel | Hosting | DPF (certified) + EU region (Frankfurt) |
| Anthropic | LLM | SCCs via EU-resident routing |
| OpenAI (via Azure) | LLM | DPF (via Microsoft) + Azure EU nodes |
| AWS | Storage | DPF + EU region (Frankfurt) as default storage location |
| Groq, Fish Audio, xAI, AssemblyAI, Speechmatics, Inworld, Rime, Composio | Various | *Pending next review* — request current status from support |
For providers without DPF certification, Famulor has executed the EU Standard Contractual Clauses under EU Commission Decision 2021/914/EU (Module 2: Controller to Processor). These are available to enterprise customers on request.
To independently verify a provider's DPF certification: [Data Privacy Framework Participants List](https://www.dataprivacyframework.gov/list)
## 11. Data retention
Retention periods are available in your **account** and configurable per data category.
| Data category | Default | Configurable range (maximum) |
| ------------- | ------------------------------------ | ---------------------------- |
| Calls | Account default (visible in account) | 1 to 24 months |
| Contacts | Account default (visible in account) | 1 to 24 months |
| Chats | Account default (visible in account) | 1 to 24 months |
| SMS | Account default (visible in account) | 1 to 24 months |
## 12. Technical and organizational measures (TOMs)
Our security framework targets maximum traceability and isolation:
| Measure | Description |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Multi-tenancy** | Strict logical separation of customer data. Every workspace runs in an isolated environment. |
| **Reseller & white-label architecture** | A whitelabel-entitled workspace gets its own admin panel to centrally manage multiple, fully separated customer workspaces. |
| **Access control** | Access follows least-privilege [workspace roles](/settings/workspaces). Every user can enable [two-factor authentication](/account-security) on top of their password. |
| **User-controlled data retention** | To implement GDPR's storage-limitation principle, users can independently configure automatic deletion windows (1 to 24 months) for calls, contacts, chats, and SMS. |
| **Audit logging** | **Settings → Data → Audit Log** records who changed what across the workspace, and when, for traceability. |
| **Continuity** | Automatic daily backups, encrypted and stored within the EU. |
## 13. Governance & maintenance
* This list is **reviewed quarterly**.
* Changes to the provider stack are documented in the **[Changelog](/changelog)**.
**Last updated:** 2026-09-02
## 14. Google API disclosure
Where Famulor's Google Calendar and other Google Workspace integrations use information from Google APIs, that use and any onward disclosure to other applications complies with the [Google API Services User Data Policy](https://developers.google.com/terms/api-services-user-data-policy), including its Limited Use requirements.
## Related pages
* [Support](/support)
* [Enterprise](/enterprise)
* [Data retention settings](/settings/data-retention)
# Call forwarding to Famulor
Source: https://docs.famulor.io/telephony/call-forwarding-setup
Forward calls from a phone you already have to a Famulor assistant
Don't want to buy a number or set up a SIP trunk? Forward calls from a phone you already have straight to your Famulor number — the assistant answers exactly as if it were a native line.
This forwards **your existing phone's** calls into Famulor. To bring numbers you already own at a SIP provider instead, see [BYO SIP trunk](/telephony/sip-trunks).
## Types of forwarding
Both are configured on your phone or with your mobile carrier — not inside Famulor:
* **Unconditional** — every call goes straight to your assistant. Nobody reaches your personal line directly.
* **Conditional** — only calls you don't answer (busy, unreachable, or no answer within a set time) are forwarded. Your phone rings first.
## Forward calls from your phone's settings
First, [buy a marketplace number](/telephony/phone-numbers) or bring one via [BYO SIP trunk](/telephony/sip-trunks) and assign it to an assistant. Then forward your existing line to it:
1. Open **Settings**
2. Tap **Phone**
3. Tap **Call Forwarding**
4. Turn on **Call Forwarding**
5. Enter your Famulor number under **Forward To**
1. Open the **Phone** app
2. Tap the **⋮** menu → **Settings** → **Calls**
3. Tap **Call Forwarding**
4. Choose a forwarding type
5. Enter your Famulor number and confirm
Exact steps vary by Android version and manufacturer.
## Forward calls with dial codes
Most mobile networks also support universal GSM feature codes — dial these directly from the keypad, using your Famulor number as the target:
| Action | Code |
| ----------------------------- | ------------------------------------------------------------- |
| Forward all calls | `**21*[Famulor number]#` |
| Forward when busy | `**67*[Famulor number]#` |
| Forward when unreachable | `**62*[Famulor number]#` |
| Forward after a delay | `**61*[Famulor number]*[seconds]#` (5, 10, 15, 20, 25, or 30) |
| Cancel all forwarding | `##21#` |
| Cancel busy forwarding | `##67#` |
| Cancel unreachable forwarding | `##62#` |
| Cancel delayed forwarding | `##61#` |
Some carriers only support call forwarding through their own app or account portal, not these dial codes.
## Check that it works
Call your forwarded line from a different phone. The assistant should pick up, and the call appears in [History](/monitoring/history) as a normal inbound call — assigned to the assistant on your Famulor number. If nothing arrives, confirm the forwarding target is the full number in international format and that the number is assigned to an assistant.
## Next steps
Get a number to forward your calls to.
See how assistants answer forwarded calls.
# Caller ID verification
Source: https://docs.famulor.io/telephony/caller-id
Verify a number you already own so it can be presented on outbound calls
Want your own existing number — a personal line, an office line, whatever your customers already recognize — to show up on outbound calls, without buying a number or setting up a SIP trunk? Verify it as a caller ID.
Caller ID verification is outbound only. It doesn't create an inbound route — calls placed *to* that number are never answered by an assistant. To also receive calls, [buy a marketplace number](/telephony/phone-numbers) or [forward your existing line to one](/telephony/call-forwarding-setup) instead.
## How verification works
Go to **Settings → Numbers**, open the **Add a number** menu, and choose **Verify caller ID**.
Enter the number in E.164 format (for example `+4930123456`) and an optional label, then start verification.
The platform calls that number immediately and shows a short code on screen. Whoever answers keys that code in on the phone.
The status updates automatically once the code is confirmed — no page refresh needed, though you can press **Check status** to look right away. The number is now a verified caller ID.
Every attempt places a real call, so verification is rate-limited: one attempt per person and five per workspace every 15 minutes. Hit the limit and the button shows a countdown until you can start the next one.
## Using a verified caller ID
Once verified, the number appears alongside your other numbers under **Numbers**. Open **Configure** on that row and connect it to an assistant under **Outbound** — outbound calls placed by that assistant, by a campaign, or through the `make_call` API/MCP tool then present the verified number to the person you're calling.
Calls placed with a verified caller ID still count against your [daily outbound allowance](/telephony/outbound-limits), the same as marketplace numbers. Only calls placed over your own [BYO SIP trunk](/telephony/sip-trunks) skip that allowance.
If you connect numbers through a SIP trunk instead, your provider — not this verification flow — controls which caller ID is presented; configure it on the provider side.
## Legal considerations
Some countries restrict presenting a number you don't have the right to use. Verify only numbers you own or are authorized to use, and check local rules before relying on a verified caller ID for outbound campaigns.
## API and MCP
Manage caller IDs with the Public API — `GET`/`POST /api/v1/caller-ids`, `PATCH`/`DELETE /api/v1/caller-ids/{id}` — or the equivalent MCP tools: `create_caller_id`, `list_caller_ids`, `update_caller_id`, `delete_caller_id`.
# Carrier number import
Source: https://docs.famulor.io/telephony/carrier-import
Import existing Twilio, Telnyx, or Vonage numbers with automatic SIP routing
Carrier import connects your own carrier account, discovers its existing phone numbers, and creates the matching inbound and outbound SIP configuration automatically. The carrier continues to bill number rental and call termination.
## Supported carriers
| Carrier | Credentials | Inbound setup | Outbound setup |
| ------- | ------------------------ | ------------------------------------------ | ------------------------------------------ |
| Twilio | Account SID + Auth Token | Elastic SIP Trunk origination URI | Generated trunk credentials |
| Telnyx | API key | FQDN connection to the selected SIP region | `sip.telnyx.com` and generated credentials |
| Vonage | API key + API secret | Direct Numbers API SIP forwarding | `sip.nexmo.com` with API key/secret |
Secrets are encrypted at rest and are never returned by the dashboard, Public API, or MCP.
## Import a number
1. Open **Settings → Phone numbers → Add SIP integration → Import from carrier**.
2. Select the carrier, enter credentials, and choose the SIP region.
3. Select voice-capable numbers that are not already routed elsewhere.
4. Import the numbers and assign an assistant.
5. Test one inbound and one outbound call before using the number in a campaign.
The platform re-reads each selected number from the carrier before importing it. A client-supplied number can therefore never be paired with a different carrier resource.
## Vonage routing protection
Vonage numbers with an existing app, telephone, or unrelated SIP callback are marked as unavailable. Carrier import never overwrites that routing.
When a Vonage number is removed, its callback is cleared only if it still points to the exact regional SIP endpoint configured by this connection. A callback changed later in Vonage is preserved.
Do not remove or replace the carrier-side trunk, connection, or callback while a number is active. Use **Troubleshoot** to detect and safely repair supported drift.
## SIP regions and troubleshooting
The selected region determines the SIP endpoint used for inbound signaling. Changing it runs provider diagnostics and repairs imported-number routing.
**Troubleshoot** verifies:
* carrier credentials and account balance;
* provider trunk/connection or direct number routing;
* inbound and outbound connectivity;
* number and assistant assignments.
Repairs are limited to resources owned by the selected connection. Provider errors remain visible on the connection.
## Public API and MCP
The Public API exposes:
* `GET/POST /api/v1/carrier-connections`
* `GET/PATCH/DELETE /api/v1/carrier-connections/{id}`
* `GET /api/v1/carrier-connections/{id}/available-numbers`
* `POST /api/v1/carrier-connections/{id}/import`
* `DELETE /api/v1/carrier-connections/{id}/numbers/{numberId}`
* `POST /api/v1/carrier-connections/{id}/troubleshoot`
Use the `sip_trunks:read` or `sip_trunks:write` scope. Equivalent MCP tools are `list_carrier_connections`, `create_carrier_connection`, `get_carrier_connection`, `update_carrier_connection`, `list_carrier_available_numbers`, `import_carrier_numbers`, `remove_carrier_number`, `delete_carrier_connection`, and `troubleshoot_carrier_connection`.
Carrier import is the fastest option for Twilio, Telnyx, and Vonage. For another SIP provider, use [BYO SIP trunk](/telephony/sip-trunks).
# Famulor Loop
Source: https://docs.famulor.io/telephony/famulor-loop
Use the built-in business phone system on web, mobile, and registered desk phones.
Famulor Loop gives every enabled workspace member a personal extension, availability status, registered devices, and personal call recents.
## Availability
Loop becomes available when it is included in the workspace plan, enabled in workspace settings, enabled for your membership, and connected to an active [number purchased through Famulor](/telephony/phone-numbers).
Loop access is a member feature, not a separate workspace role. Only the workspace owner can turn it on or off for each member.
## Personal phone workspace
Use Loop to:
* set your status to available, busy, do not disturb, or offline;
* call from the web or mobile softphone;
* register and revoke your own devices;
* find available colleagues by name or extension;
* see your personal calls under Loop Recents.
Loop Recents are separate from the omnichannel assistant History. Your role continues to determine whether you can view assistant history.
Managed clients appear in Devices as **Loop Web Phone**, **Loop iOS App**, or **Loop Android App**. You can rename or revoke your own devices. Names you assign to external SIP phones remain unchanged.
To register a desk phone or another third-party SIP client, add it under **Devices** — a workspace owner or admin creates the device and picks the Loop member it belongs to. Famulor then shows the registration details: SIP URI, server, username, password, and port/transport. The password appears only at that moment, so copy it into the phone or client straight away; the other fields stay readable on the device afterwards. **New password** issues a fresh one and invalidates the old immediately, so update every client that was still using it.
## Popout window
Loop can also be popped out of the dashboard into its own browser tab or window — no extension needed. Select the expand icon in the softphone dock to open it; the main Loop page then shows a **Show Loop tab** prompt that brings the popout back into view.
## Chrome extension
Famulor Loop is also available as a Chrome side panel — a compact dialer that stays open next to whatever tab you're working in, so you don't need the full dashboard open to take a call.
Install **Famulor Loop** from the Chrome Web Store, then open its side panel from the toolbar icon. **Alt + Shift + L** opens it from anywhere in Chrome.
Open `https://app.famulor.io/device` in a signed-in browser tab — the side panel has a button for it. The page shows a 4-digit PIN, valid for two minutes and usable once.
Enter that PIN in the side panel and connect. The browser then appears in Devices as **Chrome extension**, and you can revoke it there like any other client.
From the side panel you can dial and receive calls; mute, use the keypad, and end an active call; and keep an accepted call running even if you close the panel. Notifications cover incoming, missed, and failed calls — accept or decline an incoming call from the panel, or straight from the notification where your browser and operating system offer those buttons. The panel also shows your call history and the assistant conversations you're authorized to see, without opening the full dashboard. Chrome asks for microphone access the first time you call from it.
Calling from the extension needs Famulor Loop enabled for your membership, the same as any other Loop client — see Availability above. Without it, the panel hides the dialer and shows only the conversations you're authorized to see.
## Record an active call
The web softphone, Chrome extension and mobile call screen include a recording icon for supported active Loop calls. Choose **Start recording** to record and **Stop recording** to stop capturing audio. The recording indicator changes after the action is confirmed. You can start recording again during the same call.
You must be an enabled Loop member participating in the call with permission to control it. An ended or unsupported call cannot be recorded through this control. Calls connected from an assistant may use a separate recording lifecycle. If workspace automatic recording is enabled, the call may already be recording when you answer; use the confirmed indicator to check.
Loop recording charges use the actual recorded sections, excluding paused time. A new recording after a stop can be billed as a separate recording, with its own started-minute rounding. The final charge appears after processing. These controls do not change an assistant's recording setting or the workspace's automatic recording default. See [recording charges](/billing/minutes#call-recording) for the differences between assistant, Loop and voicemail recordings.
User-owned credentials can read the state with `GET /api/v1/loop/recording` and request an action with `POST /api/v1/loop/recording`, using the public Loop call ID. Reads require **loop:read**; actions require **loop:write** and permission to control the call. Use a unique idempotency key for each action and reuse it only when retrying that same action. MCP provides `get_loop_recording` and `set_loop_recording`; a recording action requires an explicit user request.
## Team usage
When Loop is available, the Usage page adds Loop-only statistics for the selected period: calls, minutes, customer credits, answer rate, inbound and outbound trends, and a breakdown by team member. This section is hidden when Loop is unavailable.
## Personal working hours
Set a weekly schedule and timezone in **Softphone → Settings** when assistant transfers should reach you. Your manual Busy, Do not disturb, or Offline status, active calls, and registered clients still take priority.
**When you cannot be reached** is disabled by default. You may opt into a validated cold-transfer destination, an active assistant, or an existing visible routing rule. This applies only to direct assistant transfers to you or your extension; it does not silently change phone-number routes, ring groups, or queues. A successful assistant handoff is terminal.
User-owned API credentials can read or replace the schedule, fallback, and Recall appointment calendar with `GET /loop/availability` and `PATCH /loop/availability`. A null timezone inherits the workspace timezone. Omitting `fallback` or `recall_appointment_calendar_id` preserves the current value.
## Dialing country
In Softphone Settings, choose the personal default country used for numbers entered without an international country code. For example, a German mobile number beginning with `0170` is converted to `+49` format before the call starts. A number that already begins with `+44` keeps that country code, and internal Loop extensions are never expanded.
User-owned integrations can read or update this preference with `GET /loop/preferences` and `PATCH /loop/preferences`.
## Recall
Recall keeps follow-up requests assigned to you when a transfer was missed or a caller asked to be called back. From the softphone, you can call the person yourself, ask a selected assistant to connect the person to you, ask the assistant to arrange an appointment, or mark the item as resolved. Choose the calendar used for Recall appointments under Softphone → Settings. Connect calendars on the [Booking page](/assistants/calendar-booking) first, then select one here. After you start an assistant, the softphone shows that the assistant is calling instead of the Recall details.
`GET /loop/recalls` returns only Recall items assigned to the authenticated member, including for owners and admins. Use `POST /loop/recalls/{id}/actions` for the available actions. A successful assistant start becomes the remembered choice for that member.
The application can show scheduled assistant callbacks and personal Recall requests in the same callback workspace. Their public resources remain separate: existing scheduled callback integrations continue to use `/scheduled-callbacks`, while personal Recall integrations use `/loop/recalls`.
## Workspace call routing
Workspace owners and admins can manage the same Loop configuration from the app, REST API, or MCP:
* workspace availability, default phone number, dialing country, recording, and default routing rule;
* ring groups with simultaneous, sequential, or round-robin ringing, per-member delay, ring timeout, and optional presence filtering;
* call queues with atomic round-robin, sequential or longest-idle routing, wait time, wrap-up time, member order, per-member capacity, and an overflow rule;
* ordered routing rules for members, extensions, groups, queues, assistants, another rule, or an external number;
* inbound destinations for active phone numbers purchased through Famulor.
Use `PATCH /loop` for workspace settings and the `/loop/ring-groups`, `/loop/queues`, `/loop/routing-rules`, and `/loop/number-routes` resources for call routing. Read operations require `loop:read`; changes require `loop:write`. User-owned credentials must belong to a workspace owner or admin.
Ring-group and queue writes accept ordered member assignments, including a delay for ring-group members and concurrent-call capacity for queue members. The older flat member list remains accepted for compatible integrations.
Routing rules share one optional weekly schedule. Each step runs always, during those hours, or outside those hours, and continues only for selected pre-answer outcomes: unavailable, busy, timeout, or error. An answered person or assistant always stops the rule. Updates are atomic and cyclic references are rejected.
```mermaid theme={null}
flowchart TD
A(["Call enters the routing rule"]) --> B{"Step's schedule condition"}
B -->|"step runs"| C["Attempt the step's target"]
B -->|"step skipped — no outcome"| N{"Another step in the rule?"}
C --> D{"Outcome"}
D -->|"answered"| E(["Rule stops — call handled"])
D -->|"a selected pre-answer outcome"| N
D -->|"any other pre-answer outcome"| Z(["Rule ends — nobody took the call"])
N -->|"Yes"| B
N -->|"No"| Z
```
## API and MCP
The REST API exposes Loop access and settings, the directory, personal presence, working hours and dialing preferences, registered-device metadata, device revocation, personal call recents and Recall items, and workspace call routing. Use the `loop:read` and `loop:write` permissions. Personal preferences, working hours and Recall require a user-owned credential associated with a workspace member.
Equivalent MCP tools are available in the Telephony toolset. Devices use `list_loop_devices`, `rename_loop_device`, and `revoke_loop_device`; personal schedules use `get_loop_availability` and `update_loop_availability`; dialing preferences use `get_loop_dialing_preferences` and `update_loop_dialing_preferences`; Recall uses `list_loop_recalls` and `act_on_loop_recall`. Public responses never include registration secrets, raw failure diagnostics, or internal cost data. Usage is shown in minutes and credits.
New registration details are displayed once in the authenticated application. They are not available through the public API or MCP.
# Inbound & outbound calls
Source: https://docs.famulor.io/telephony/inbound-outbound
How calls reach assistants — and how assistants place calls
## Inbound calls
Route any number — bought in the [marketplace](/telephony/phone-numbers) or brought via [BYO trunk](/telephony/sip-trunks) — to an assistant:
1. **Phone numbers → select number → assign assistant.**
2. Incoming calls are answered by that assistant, using its greeting mode (speak first, or wait for the caller).
3. Recording (with [consent handling](/assistants/conversation-quality#what-the-consent-covers) if enabled), transcription, and call events happen automatically.
The number → assistant mapping resolves per call, so you can reassign numbers at any time without touching the number itself.
## Outbound calls
Three ways to place calls:
* **Single call from the UI** — on an assistant page, enter a number and call: ideal for testing.
* **API / MCP** — `make_call` with `assistant_id` and `to_number`, plus optional lead data the assistant can use in conversation (name, custom fields). See the [API Reference](/api-reference/introduction).
* **Campaigns** — bulk outbound over a lead list with dialer logic; see [Campaigns](/campaigns/overview).
Outbound behavior details:
* The assistant greets **only after the callee picks up** (no talking into ringing).
* Unanswered outcomes map to clean statuses: `busy`, `no_answer`, `failed` — campaign retry logic builds on these.
* With **greeting mode: user speaks first**, the assistant waits for the callee's "Hello?" — noticeably more natural for cold calls.
* Optional **answering machine detection (AMD)** classifies who picked up (human / voicemail / IVR) and can drop a configured voicemail message; see [Dialer & compliance](/campaigns/dialer-and-compliance#amd--voicemail).
### Failure guidance
`POST /api/v1/calls` returns the queued call immediately. Poll `GET /api/v1/calls/{id}`, use
`get_call`, or consume `call.completed` to receive the final result. Failed
outbound calls include a provider-neutral `failure` object:
```json theme={null}
{
"operation": "outbound_call",
"code": "no_answer",
"message": "The destination did not answer before the call timed out.",
"retryable": true,
"action": "retry_later"
}
```
Common codes include `busy`, `declined`, `no_answer`,
`temporarily_unavailable`, `invalid_destination`,
`authentication_failed`, `destination_forbidden`, `trunk_unavailable`, and
`no_outbound_trunk`.
`retryable` is guidance for your integration. It does not modify campaign retry
settings.
If a cold or warm transfer fails while the original call remains active, the
call's event log contains `call_transfer_failed` or `warm_transfer_failed`.
Those events use the same `failure` shape with `operation: cold_transfer` or
`warm_transfer`.
## Web calls
Every assistant can also be called **from the browser** — used by the built-in test call and the embeddable [web widget](/web-widget). Web calls appear in the call history with direction `web`.
## Call results
Every call — regardless of direction — produces: a transcript, duration and status, provider-neutral failure guidance when applicable, per-turn latency metrics, an event log (tool calls, transfers, consent, node transitions), optional recording, and a `call.completed` [webhook](/api/tools-and-webhooks#receive-call-results-with-webhooks).
# Outbound call limits
Source: https://docs.famulor.io/telephony/outbound-limits
Workspace-wide daily protection for calls placed through integrated numbers
## What the daily limit covers
The daily outbound allowance is shared by **every assistant in the workspace**. A call counts when it is started through:
* a phone number provided through the [number marketplace](/telephony/phone-numbers), or
* your own [verified caller ID](/telephony/caller-id) when it uses the integrated outbound route.
Single calls, campaigns, scheduled callbacks, automations, the REST API, and the `make_call` MCP tool all use the same workspace counter. Parallel requests are reserved atomically, so the allowance cannot be exceeded by starting several calls at once.
Calls that reach `busy`, `no_answer`, or another carrier outcome still count because the outbound attempt has already been placed.
## What is always unlimited
These call types do not use the daily allowance:
* inbound calls,
* browser and web-widget calls,
* outbound calls through your own [SIP trunk](/telephony/sip-trunks) or BYOC connection, and
* [WhatsApp voice calls](/telephony/whatsapp-voice).
Connect a provider such as Twilio, Telnyx, Zadarma, DIDLogic, MIXVOIP, or any SIP-compatible carrier under **Settings → Numbers** when you need unlimited outbound calling.
## View usage and request an increase
Open **Settings → Limits** to see:
* calls used and remaining today,
* the current daily allowance,
* the next reset time in the workspace timezone, and
* the latest increase-request status.
Workspace owners and admins can submit one pending increase request with a requested daily limit, a business reason, and an optional business website. The support team reviews requests and may approve a different final allowance. Approved changes apply to the complete workspace, including every assistant.
You can also ask **Milian** to increase your daily outbound limit. An editable form appears directly in the chat: choose the desired daily allowance or **Unlimited**, enter your reason, and optionally add your business website. Review the details and select **Submit limit request**. Preparing the form does not submit it; after submission, the request awaits review and your current limit stays in place until approval. Check **Settings → Limits** for the review status.
Adding credits pays for usage and does not raise the daily allowance. After changing plans, check the current limit before placing more calls.
## API and MCP
Use the public API with the `settings:read` or `settings:write` scope:
* `GET /api/v1/settings/outbound-limits`
* `POST /api/v1/settings/outbound-limits/requests`
Equivalent MCP tools:
* `get_outbound_limits`
* `request_outbound_limit_increase`
When the allowance is exhausted, new integrated outbound calls return HTTP `429 rate_limited`. The response includes the next reset time; inbound, web, and BYOC calls remain available.
# Buying phone numbers
Source: https://docs.famulor.io/telephony/phone-numbers
Search, buy, and manage numbers through the platform marketplace
The platform includes a **number marketplace**: search available numbers by country and type, buy them in a click, and they are routed to your account's telephony automatically — no carrier account needed.
## How buying works
Go to **Settings → Numbers → Add a number → Buy a number** and pick a country. When more than one number type is buyable, or you have a workspace/user regulatory bundle, tabs appear above the list (Local, Mobile, and your bundle name). A single type with only a global unlock shows every available number with no tabs — same as before.
Many countries legally require identity or address verification before a number can be activated — see below.
The monthly price and any setup fee are shown up front. Complete the secure checkout. The number remains pending and cannot receive or place calls until payment is confirmed.
A verified payment event provisions routing and activates the number. Failed, expired, or unpaid purchases automatically release the held number and grant no call access.
Point the number at an assistant — inbound calls are answered from that second on. The same number can be used as outbound caller ID.
## Country availability & pricing
Available countries and number types are shown in the marketplace. It sells **local, mobile, and national** numbers; **toll-free is not currently sold**. The checkout shows the monthly price and any one-time setup fee before purchase. Prices differ by country and number type.
## Regulatory bundles
Some countries and number types require **identity verification** before you can buy. The buy page shows only the types that are still locked. Everything else can be purchased immediately.
After regulatory approval, eligible numbers become available for purchase and calling.
### How to verify
1. Open **Settings → Verification** (or **Buy a number → Custom number / Submit verification**).
2. The country list includes countries that require regulatory verification. API clients can use `GET /api/v1/phone-numbers/verifications/catalog`.
3. Choose country, number type, end-user type (business or individual), and the required area code or prefix. National digits such as 0831 become +49831 for Germany. The form fields and accepted documents are loaded **for that combination** from the live regulation catalog.
4. Submit the case. Status updates appear on the Verification page (`pending review` → `approved` / `rejected`). If rejected, submit a **new** case with corrected details.
5. After approval, marketplace search/purchase for that country and type is unlocked for the workspace.
You can also:
* List catalog / cases via the public API (`/api/v1/phone-numbers/verifications`, `/api/v1/phone-numbers/verifications/catalog`)
* Delete a draft or failed case with `DELETE /api/v1/phone-numbers/verifications/{id}`
* Use MCP tools `list_verification_catalog`, `list_number_verifications`, `submit_number_verification`, `get_number_verification`, `delete_number_verification`
Plan ahead for regulated countries: review often takes a few business days (varies by country and document quality).
## Outbound SMS
SMS-capable numbers (marketplace mobile numbers, or Twilio-imported numbers with SMS capability) can send outbound SMS through the platform after you enable **Allow outbound SMS** on the number’s SMS tab.
* **Marketplace numbers:** SMS credits include the platform fee plus carrier pass-through.
* **Twilio BYOC import:** SMS credits charge only the platform fee; Twilio carrier cost is billed on your Twilio account. For US 10DLC → US traffic, the number must be registered with an approved A2P 10DLC campaign in Twilio.
Public API: `POST /api/v1/sms/send`. MCP: `send_sms`. See [SMS](/api-reference/sms) for per-segment billing and the send API.
## Complimentary (plan free) numbers
Some plans include a limited number of complimentary **local** marketplace numbers for selected countries. Mobile, national, and other number types remain paid. If the workspace plan is canceled or payment remains overdue, complimentary numbers are released automatically. Paid marketplace numbers are unaffected.
Manual release of a complimentary number is **immediate** and cannot be undone.
## Releasing a paid marketplace number
When you release a paid marketplace number:
1. Renewal is canceled at the end of the current billing period.
2. The number **stays fully usable** (inbound/outbound) until that period end.
3. At period end, the number is released and can no longer be used.
Complimentary / unpaid / failed purchases are still released immediately. There is **no refund** and **no proration** — the setup fee is one-time and is never returned.
## Phone number limits
Your plan determines how many phone numbers the workspace can use.
## Carrier costs on calls
Besides the monthly number fee, call-minute pricing can vary by destination country. See [How minutes are billed](/billing/minutes).
## Choosing how to connect a number
The marketplace isn't the only way to get a number working with an assistant:
| Option | Direction | What it needs |
| ----------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------ |
| **Buy from the marketplace** (this page) | Inbound + outbound | Nothing to bring — search, buy, assign (regulated countries need verification first) |
| **[BYO SIP trunk](/telephony/sip-trunks)** | Inbound + outbound | A number you already own at a SIP-compatible carrier |
| **[Carrier import](/telephony/carrier-import)** | Inbound + outbound | A Twilio, Telnyx, or Vonage account — routing is set up for you |
| **[Verify a caller ID](/telephony/caller-id)** | Outbound only | A phone number you already own, verified once — no porting or SIP setup |
Buy a marketplace number for a new setup. Bring your own SIP trunk when you already have carrier numbers you want to keep using — or let carrier import wire them up automatically if those numbers live at Twilio, Telnyx, or Vonage. Verify a caller ID when you only need your own number to show up on outbound calls — for example, an outbound sales campaign that doesn't need to receive calls.
Want the line you already answer today to reach an assistant instead? Keep that number where it is and [forward it to your Famulor number](/telephony/call-forwarding-setup).
# Bandwidth SIP trunk
Source: https://docs.famulor.io/telephony/providers/bandwidth
Route Bandwidth numbers to the platform using account-specific signaling IPs
## Recommended profile
In Bandwidth, route the number's Voice Configuration Package to the platform SIP FQDN. In the platform, use the exact DID in `+E.164` and select **Provider source IPs**.
Bandwidth does not provide one safe global signaling allowlist for this setup. The address depends on the account, zone, product, and trunk group, and can change during SBC migrations.
Open the Bandwidth App and copy **every signaling IP** for the relevant entry under **Account → Trunk Group Configurations**. Choose the addresses for the transport in use; standard SIP and SIP-over-TLS can use different endpoints. Do not substitute media ranges or an address copied from another Bandwidth customer.
Bandwidth's documented digest realm is for customer-to-Bandwidth termination. For Bandwidth-to-platform delivery, authenticate by the account's current source IPs unless Bandwidth explicitly enables a different downstream method for your account.
## Validate the setup
Call the exact DID externally. Confirm a new inbound record, the assigned assistant, and two-way audio. Save a screenshot or export of the current Bandwidth trunk-group addresses with the setup record so future changes can be compared safely.
Sources: [Bandwidth Vapi integration](https://dev.bandwidth.com/docs/voice/integrations/vapi/), [Bandwidth Voice Configuration Packages](https://dev.bandwidth.com/docs/universal-platform/create-a-vcp/). Accessed 22 August 2026.
# DIDLogic SIP trunk
Source: https://docs.famulor.io/telephony/providers/didlogic
Route DIDLogic numbers to the platform and allow current regional gateways
## Recommended profile
Set the DIDLogic destination to `+[number]@;transport=tcp`. Keep the exact `+E.164` DID on the platform trunk and choose **Provider source IPs**. DIDLogic credentials are used for platform-to-DIDLogic outbound calls; they do not document digest toward an arbitrary inbound SIP URI. DIDLogic rejects a weak outbound password at save time — use at least 12 characters with mixed case.
The official DIDLogic FAQ listed these unique signaling gateways on 22 August 2026:
```text theme={null}
89.149.192.7/32
23.19.63.1/32
5.150.254.205/32
157.230.96.24/32
159.8.84.235/32
188.42.84.76/32
119.9.12.222/32
131.203.181.17/32
161.202.135.82/32
102.130.116.205/32
138.197.143.154/32
23.83.156.0/32
192.241.183.87/32
169.57.132.146/32
```
DIDLogic recommends DNS-name firewall rules for resilience. The platform source-IP field accepts addresses/CIDRs, so refresh the official FAQ immediately before saving.
## Validate the setup
Call the DID externally and confirm the platform created an inbound record, routed the assigned assistant, and carried audio both ways.
Source: [DIDLogic gateway FAQ](https://didlogic.com/faq/). Accessed 22 August 2026.
# Easybell SIP trunk
Source: https://docs.famulor.io/telephony/providers/easybell
Route an Easybell DID to the platform with FQDN and source-IP authentication
## Recommended profile
| Setting | Value |
| ------------------------------- | ---------------------------------------------------------------------- |
| Easybell destination | The platform SIP FQDN |
| Platform inbound authentication | **Provider source IPs**; do not enable digest for this forwarding path |
| Number | Exact DID in `+E.164` |
| Transport | TCP where possible; TLS only with the TLS-specific source list |
Easybell treats username/password registration, Trusted IP, and Trusted FQDN as different connection modes. For inbound FQDN delivery, point Easybell to the platform SIP FQDN, then authenticate the incoming traffic on the platform by source address.
## Choose the Easybell path
Make sure the FQDN connection is enabled for the Easybell product. Configure the platform SIP FQDN as the trusted destination without a `sip:` prefix, send the DID in `+E.164`, and use the source list that matches the selected transport.
The FQDN feature on a plain SIP trunk isn't self-service — request it by emailing [support@easybell.de](mailto:support@easybell.de). It costs roughly €10/month and can take several days to activate, so ask for it before you plan a go-live date.
In the Easybell Cloud PBX, create a **Resource** of type **FQDN**, assign the public number, and enter the platform SIP URI under **Call handling → Forwarding → FQDN** without the `sip:` prefix. Cloud PBX delivery does not necessarily come from the direct-trunk networks below. A separate candidate list has been reported for Cloud PBX Pro signaling — `62.144.211.104`, `195.52.221.134`, `195.52.221.137` — but it is unverified: treat it as a starting point, and confirm the current Cloud PBX signaling sources with Easybell or from a verified SIP trace before saving them as a production allowlist.
Cloud PBX Pro can allow the connected service to transfer a call back to an internal extension. Enable forwarding on the FQDN resource and use a SIP target such as `200@easybell`. Easybell documents this as internal-only; it does not permit forwarding through that resource to an external PSTN number.
## Official Easybell networks
For UDP/TCP, Easybell publishes:
```text theme={null}
195.185.187.0/27
195.52.221.128/27
```
For TLS, Easybell publishes:
```text theme={null}
195.185.187.0/27
212.172.204.95/32
212.172.58.207/32
```
Choose the list that matches the transport configured at Easybell. These are signaling sources for the receiving system, not outbound platform addresses.
## Validate the setup
Save the exact DID and source addresses, assign the number to an assistant, and call it externally. Confirm a new inbound call, the correct assistant, and two-way audio in **History**.
Sources: [Easybell FQDN authentication](https://www.easybell.de/hilfe/fragen/fragen-zum-telefonanschluss/antwort/sip-trunk-authentifizierung-per-fqdn-domain-einrichten/), [Easybell Cloud PBX FQDN resource](https://www.easybell.de/hilfe/cloud-telefonanlage/antwort/fqdn-anbindung-ki-dienste-in-die-cloud-telefonanlage-integrieren-1/), [Easybell Trusted IP](https://www.easybell.de/hilfe/fragen/fragen-zum-telefonanschluss/antwort/trusted-ip-bei-sip-trunks-einrichten/). Accessed 22 August 2026.
# Other and custom SIP providers
Source: https://docs.famulor.io/telephony/providers/other-custom
Safe setup rules for PBXs and providers without a verified global signaling allowlist
A saved hostname proves only that an endpoint was entered. It does not prove direction, authentication, source addresses, or a successful inbound call. Keep the exact DID, route it to the platform SIP FQDN, and obtain current provider-to-destination authentication details. If no stable list is published, ask support for the account's complete **SIP-signaling source CIDRs** and failover regions. Never use media ranges or another customer's addresses.
Running your own PBX or contact-center platform — 3CX, Asterisk/FreePBX, Starface, Genesys Cloud, Five9, or Aircall? See [PBX & contact center platforms](/telephony/providers/pbx-and-contact-center) for step-by-step setup, codec settings, and the failure modes specific to each.
If a provider doesn't support a static SIP trunk at all, you don't have to give up on the number. [Forward it](/telephony/call-forwarding-setup) to a number purchased through the platform for inbound calls, and place outbound calls from that platform number instead.
**Status:** `sip.1und1.de` is normally a registrar/termination host, not evidence of external FQDN forwarding. No verified global source list is included. **Action:** confirm product support, sent DID format, and all signaling sources with 1&1.
**Status:** Fonial documents SIP users and trunking, but SIP-URI forwarding is account-dependent. `sip.plusnet.de` is an outbound host, not an inbound allowlist. SIP trunking with the platform requires Fonial's paid **PLUS** plan — the free tier can't be used this way. **Action:** configure outbound separately and obtain current forwarding/source details from Fonial. Expect the SIP user to show **Offline** in Fonial's dashboard permanently; that's expected, since the platform never sends a SIP REGISTER, not a sign the integration is broken.
**Status:** a `localphone.com` endpoint alone is not a verified inbound profile. **Action:** confirm external SIP-URI routing, DID format, transport, and signaling sources with Localphone.
**Status:** the hostname can identify a PBX or reseller; no global list is verified. **Action:** identify the actual operator and obtain account-specific public signaling addresses.
**Status:** routing a DID to a SIP URI is supported, but auth and sources follow current account/trunk documentation. DIDWW uses two separate trunks — inbound routes to the platform SIP FQDN, and outbound authenticates against `out.didww.com`. **Action:** use current DIDWW sources; never reuse DIDLogic addresses. Send outbound numbers in E.164 **without** the leading `+` — DIDWW expects that exact format, and it's an easy detail to miss.
**Status:** credentials and routing are account-specific; no global list is verified here. Zadarma offers two integration paths — a PBX extension, or a direct SIP connection with **External Services → SIP URI** enabled per number. **Action:** confirm FQDN forwarding plus documented downstream Digest or current signaling CIDRs. Either way, check Zadarma's **Voice Geographic Permissions**: international outbound dialing is blocked by default per destination country, and a call to an unlisted country fails silently rather than with an obvious error.
**Status:** capabilities vary by product and region. sipcall's default trunk type registers (**Endgerät**); the platform needs the non-registering, static **Anlagenanschluss** mode instead — not the option a new sipcall customer would normally pick. **Action:** ask support for external SIP-URI routing, number format, transport, and current sources. Use Digest authentication, and set codecs to G.711 a-law with Opus and G.722 disabled (the Swiss default). If outbound calls get a 403, check that the caller ID is verified on the account.
**Status:** generic SIP/BYOC depends on the purchased product. RingCentral has no wholesale SIP trunk for retail accounts; connect by provisioning a **Generic SIP IP Phone** instead, which requires **MVP/RingEX Standard or higher** — entry plans don't expose it. **Action:** confirm external SIP destination support and request current regional signaling ranges. Always point at the global `sip.ringcentral.com` host, never a regional `sipXX.ringcentral.com` address (those are reserved for RingCentral's own desk phones). A newly created SIP endpoint needs one to two minutes to propagate through RingCentral's anti-flood protection — testing immediately produces spurious 403/404 errors, and retrying during that window can extend the lockout.
**Status:** Voice Connectors use region-specific signaling information. Chime's Voice Connector defaults to **Encryption: Enabled**, which requires TLS and SRTP — if the platform side of the trunk falls back to plain UDP on port 5060, the call fails with no media and no obvious error. **Action:** use the current data for the selected AWS region; never reuse another region's addresses. The outbound host follows `.voiceconnector.chime.aws`. Chime also gates outbound by **Calling Plan** — a destination country not explicitly enabled on the AWS account is blocked, independent of any platform-side dialing permissions.
**Status:** no verified direct external-FQDN profile is documented here. **Action:** treat it as unsupported until Placetel confirms route, number format, auth, transport, and source ranges in writing. No static trunk? Use the fallback above.
**Status:** capabilities and SBC addresses vary by country/product. **Action:** request the exact external SIP route and regional source networks for the account. No static trunk? Use the fallback above.
**Status:** Cloud PBX interconnect is product-controlled; no global list is asserted. **Action:** use a support-assisted setup and only the destination/source networks supplied by NFON. No static trunk? Use the fallback above.
**Status:** trunking and forwarding are product-specific; no global list is asserted. **Action:** confirm external SIP-URI routing and current signaling sources before saving. No static trunk? Use the fallback above.
**Status:** no current provider-to-platform authentication profile is documented here. **Action:** identify the exact product and region, then obtain the current FQDN-routing method and complete signaling sources from the provider or account portal.
**Status:** a saved hostname or credential mode is not proof of downstream Digest support. **Action:** confirm the account's external SIP destination support, DID format, transport, and current public signaling sources.
## Required confirmation
Ask whether the DID can be delivered to an external FQDN without REGISTER; the exact DID format in the Request-URI; whether the provider authenticates toward the destination with Digest and where those origination credentials are set; otherwise all signaling CIDRs and failover regions; TCP 5060 or TLS 5061; and whether SRTP is required.
Only an external call with a platform inbound record, the assigned assistant, and two-way audio confirms the integration.
Reject allowlist entries that contain prose, placeholders, hostnames, or unrelated public resolvers such as `8.8.8.8`. A provider network written without its CIDR prefix is only one host and must not be silently expanded or corrected.
Sources: [DIDWW](https://doc.didww.com/), [Fonial](https://www.fonial.de/hilfe/trunking/einrichtung-trunking), [Amazon Chime](https://docs.aws.amazon.com/chime-sdk/latest/ag/voice-connectors.html), [Zadarma](https://zadarma.com/en/support/), [sipcall](https://www.sipcall.ch), [RingCentral](https://developers.ringcentral.com/), [Placetel](https://www.placetel.de/hilfe), [Peoplefone](https://www.peoplefone.com/), [NFON](https://support.nfon.com/), [Sipgate](https://help.sipgate.de/). Accessed 22 August 2026.
# SIP provider guides
Source: https://docs.famulor.io/telephony/providers/overview
Provider-specific inbound routing, authentication, signaling IPs, and test steps
Use these guides when a carrier sends an existing number to the platform by SIP. Provider settings and signaling networks can change; the source pages below were checked on **22 August 2026**. Re-check the linked provider source before changing a production trunk.
## The rule that prevents most inbound failures
The platform SIP FQDN is the **destination** for the provider's INVITE. It is not an authentication method. Configure both sides:
1. Copy the platform SIP URI from **Settings → Numbers → Add a number → Add SIP integration**.
2. Route the provider's number to that FQDN.
3. Create the platform trunk with the **exact DID** the provider sends. Use `+E.164` unless the provider guide explicitly says otherwise. A SIP extension is not a wildcard.
4. Choose **SIP username/password** only when the provider documents digest authentication toward the destination. Otherwise choose **Provider source IPs** and enter the provider's current SIP-signaling IPs or CIDRs.
5. Keep outbound credentials and the provider termination host separate from inbound authentication.
Never use RTP/media ranges as Provider source IPs, never copy an IP list from another carrier, and never remove the exact DID to make matching broader.
## Supported guides
| Provider | Platform inbound authentication | Source of signaling addresses |
| --------------------------------------------------------------- | ------------------------------- | -------------------------------------------------------------- |
| [Easybell](/telephony/providers/easybell) | Provider source IPs | Published networks; observed addresses are labelled separately |
| [Twilio](/telephony/providers/twilio) | Provider source IPs | Global Twilio signaling CIDRs |
| [Telnyx](/telephony/providers/telnyx) | Provider source IPs | Two addresses for the selected inbound region |
| [Plivo](/telephony/providers/plivo) | SIP username/password preferred | Origination-URI digest or Plivo signaling CIDRs |
| [Wavix](/telephony/providers/wavix) | Provider source IPs | Current Wavix portal gateway list |
| [Sinch](/telephony/providers/sinch) | Provider source IPs | Sinch Elastic SIP Trunking CIDRs |
| [DIDLogic](/telephony/providers/didlogic) | Provider source IPs | Current DIDLogic gateway table |
| [Vonage](/telephony/providers/vonage) | Provider source IPs | Vonage SIP source subnets |
| [Bandwidth](/telephony/providers/bandwidth) | Provider source IPs | Account-specific trunk-group addresses |
| [Other and custom providers](/telephony/providers/other-custom) | Confirm with the provider | Never infer from a saved hostname |
Connecting your own PBX or contact-center platform instead of a carrier — 3CX, Asterisk/FreePBX, Starface, Genesys Cloud, Five9, or Aircall? See [PBX & contact center platforms](/telephony/providers/pbx-and-contact-center).
## Prove the setup
Call the exact DID from an external phone. The setup is only confirmed when a new **inbound** item appears in **History**, the assigned assistant joins, and two-way audio works. Ringing, a delay, or a provider-side call duration alone does not prove that the call reached the platform.
Provider-specific sources are linked from each guide. Check the provider's current documentation before changing a production trunk.
# PBX & contact center platforms
Source: https://docs.famulor.io/telephony/providers/pbx-and-contact-center
Connect your own 3CX, Asterisk, Starface, Genesys Cloud, Five9, or Aircall deployment as a SIP trunk
If your organization runs its own PBX or a contact-center platform, you can connect it the same way you'd connect any SIP trunk — no number porting required. Start with [SIP provider guides](/telephony/providers/overview) for the shared mechanism (the platform SIP FQDN, the exact DID, and inbound authentication); this page covers what's specific to six PBX and contact-center platforms, including a few things that look broken but are expected.
| Platform | Access requirement | Watch for |
| ------------------ | ------------------------------------------------- | ----------------------------------------------------------- |
| 3CX | StartUP PRO, or a self-managed/Dedicated instance | Inbound needs a two-part routing rule, not just the trunk |
| Asterisk / FreePBX | Self-hosted | NAT settings; calls dropping at exactly 30 seconds |
| Starface | Any | Transfers must be SIP transfers, never PSTN forwarding |
| Genesys Cloud | BYOC Carrier | Non-standard ports 32681/32682; never allow all SIP sources |
| Five9 | Enterprise, via a support ticket | 12-hour hard call cap; SIP REFER only |
| Aircall | Enterprise plan | Inbound only — no outbound caller ID over SIP |
3CX's **Generic SIP Trunk (IP Based)** connection type is only available on **StartUP PRO** and self-managed/Dedicated instances — the entry StartUP tier doesn't expose it.
1. Create a Generic SIP Trunk in 3CX with IP-based authentication, not SIP registration.
2. Point it at the platform SIP FQDN, set the trunk transport to TCP (UDP fragments large INVITEs), and restrict codecs to PCMA/PCMU with RFC2833 DTMF — disable Opus and G.722.
3. Set the trunk's **From: Display-Name** and **Remote-Party-ID** to `OriginatorCallerID` so the assistant sees the real caller, not 3CX's own system number.
4. Configure inbound in two parts: an outbound rule with a distinct prefix (for example `999`) routed to the trunk, and an inbound rule that dials `999` back through that same outbound rule.
5. Assign the DID on the platform side and test.
The outbound rule alone delivers nothing on its own. The pairing in step 4 — an outbound rule plus a matching inbound rule dialing through it — is what actually routes an inbound call to the assistant. Skipping it is the most common cause of "trunk configured, calls never arrive."
Configure a static, non-registering trunk in both directions — Asterisk never sends the platform a SIP REGISTER, and the platform never expects one.
### FreePBX (GUI)
Add a generic SIP trunk pointed at the platform SIP FQDN and disable registration. Restrict codecs to PCMA/PCMU. If Asterisk sits behind NAT, set the external media and signaling addresses and the local network range so RTP negotiates correctly, and forward the RTP port range at the firewall.
### Raw config (pjsip.conf)
```text theme={null}
[platform]
type=endpoint
context=from-platform
disallow=all
allow=ulaw
allow=alaw
aors=platform
auth=platform-auth
outbound_auth=platform-auth
from_domain=
from_user=
direct_media=no
rewrite_contact=yes
[platform]
type=aor
contact=sip:
[platform-auth]
type=auth
auth_type=userpass
username=
password=
[platform]
type=identify
endpoint=platform
match=
```
The sample uses whatever transport your Asterisk install already defines. If you name your transports explicitly, add a matching `transport=` line to the endpoint — the platform SIP URI advertises TCP by default.
If calls connect but drop at exactly 30 seconds, the endpoint is missing a re-INVITE across NAT. `direct_media=no` and `rewrite_contact=yes` (already in the sample above) fix it.
Connect Starface with a host/IP-based SIP line, not SIP REGISTER — the line will show **not registered** in Starface's status view afterward. That's expected, not a fault.
1. Create the SIP line as host/IP-based, pointed at the platform SIP FQDN, and assign the number.
2. Enable **CLIP No Screening** so the real caller ID passes through instead of the trunk's own number.
3. For time-based routing to the assistant, use a line-prefix dial string such as `***`.
4. If audio is one-way or missing, set **Behind NAT? yes** on both the Starface server and the line.
Never use ordinary PSTN call forwarding from the assistant to transfer a call on Starface — it creates a call loop between Starface and the platform. Configure every assistant transfer on a Starface trunk as a SIP transfer instead.
Connect the platform as an external trunk under **BYOC Carrier**.
1. Create the trunk with inbound (the FQDN Genesys Cloud generates) and outbound (pointed at the platform SIP FQDN) configured as separate legs.
2. Open the non-standard ports at your firewall — **TCP/UDP 32681** and **TLS 32682** — instead of the usual 5060/5061. A firewall that only opens the standard ports fails silently.
3. Order codecs PCMU then PCMA, and remove G.722.
4. Restrict SIP Access Control to only the platform's current signaling addresses.
Never set SIP Access Control to **Allow All**. An open trunk is typically found and used for toll fraud within hours.
Provisioning the platform as an external SIP destination on a Five9 SBC is an enterprise-only integration.
1. Open a support ticket with Five9 — there's no self-service path.
2. Set codecs to G.711 only (no Opus/G.722).
3. Configure human transfers with SIP REFER — Five9 doesn't honor SIP 302 redirects.
4. Target a fully-qualified URI for every REFER (`sip:queue@sbc-{region}.five9.com`); a bare extension is silently dropped.
Five9 hard-drops any call at exactly 12 hours, regardless of activity. Account for this ceiling in long-running flows and unattended campaign calls — there is no way to extend it from the platform side.
Aircall has no wholesale SIP trunk. **SIP Forwarding** (Enterprise plan only) covers inbound only — it delivers calls to the platform, but Aircall has no SIP path for sending a call back out with an Aircall number as caller ID. To use one number in both directions, port it to a SIP-capable carrier for outbound (see [SIP provider guides](/telephony/providers/overview)) while keeping Aircall for inbound. Aircall also doesn't support SIP REFER — a transfer should place a fresh outbound call rather than attempt a cold SIP transfer.
## Validate the setup
Call the DID from an external phone and confirm a new inbound record in **History**, the assigned assistant, and two-way audio. For platforms with a distinct outbound leg (3CX, Asterisk, Genesys Cloud), place one outbound test call too — an inbound success doesn't confirm outbound is configured correctly, and vice versa.
See also [SIP provider guides](/telephony/providers/overview), [BYO SIP trunk](/telephony/sip-trunks), and [Other and custom SIP providers](/telephony/providers/other-custom).
Sources: [3CX SIP trunks](https://www.3cx.com/docs/manual/sip-trunks/), [Asterisk documentation](https://docs.asterisk.org/), [Starface knowledge base](https://knowledge.starface.de/), [Genesys BYOC Cloud](https://help.mypurecloud.com/articles/about-byoc-cloud/), [Five9 documentation](https://documentation.five9.com/), [Aircall support](https://support.aircall.io/). Accessed 22 August 2026.
# Plivo Zentrunk SIP Trunking
Source: https://docs.famulor.io/telephony/providers/plivo
Configure an authenticated Plivo Origination URI or Plivo signaling sources
## Recommended profile
In Plivo, create an Origination URI pointing to the platform SIP FQDN and assign the DID. Plivo explicitly supports `authentication_needed`, username, and password on the Origination URI. Therefore **SIP username/password** is the preferred platform inbound mode when those same credentials are configured in Plivo.
Plivo has EU points of presence in Frankfurt, London, and Dublin. Select the EU region when creating the trunk if your numbers or customers are in Germany or elsewhere in the EU — it keeps signaling closer to home and can matter for data-residency requirements.
Use the exact DID in `+E.164`. Use TCP for standard signaling. For TLS use 5061 and enable SRTP at both ends.
If digest is not enabled, select **[Provider source IPs](/telephony/sip-trunks#inbound-receiving-calls)** and allow all current Plivo signaling ranges for failover:
```text theme={null}
13.52.9.0/25
216.120.187.128/26
18.214.109.128/25
18.215.142.0/26
204.89.148.128/26
3.120.121.128/26
18.228.70.64/26
54.233.191.0/27
13.238.202.192/26
18.136.1.128/26
204.89.149.128/27
15.207.90.192/31
204.89.151.128/27
204.89.151.160/27
```
Do not configure both modes with unrelated credentials. Outbound Zentrunk authentication remains a separate provider-to-destination direction.
Plivo's **Strict Caller ID** setting (the per-number DIP profile) rejects or flags outbound calls for fraud review when the caller ID doesn't match a Plivo-verified number. Disable it, or verify the caller ID in the DIP profile, before relying on outbound calls from this trunk.
## Validate
Call the exact DID externally and confirm a new inbound record, correct assistant, and two-way audio. If using digest, a provider authentication failure must be visible before changing to IP authentication.
Sources: [Plivo Origination URI authentication](https://www.plivo.com/docs/sip-trunking/api/origination-uris), [Plivo Zentrunk networks](https://www.plivo.com/docs/sip-trunking). Accessed 22 August 2026.
# Sinch Elastic SIP Trunking
Source: https://docs.famulor.io/telephony/providers/sinch
Configure Sinch static endpoint routing and signaling CIDRs
## Recommended profile
Create a Sinch static endpoint that targets the platform SIP FQDN and assign the DID. Sinch's static-endpoint field expects the port and transport appended to the hostname, not a bare FQDN — use `:5060;transport=tcp` for standard signaling, or `:5061;transport=tls` for secure trunking.
In the platform, use the exact `+E.164` DID and **[Provider source IPs](/telephony/sip-trunks#inbound-receiving-calls)**. Sinch ACL/digest choices documented for calls into Sinch belong to outbound authentication, not the Sinch-to-platform inbound path.
Allow all eight Sinch SIP-signaling CIDRs:
```text theme={null}
206.146.131.0/28
206.146.133.0/28
206.146.134.0/28
206.146.136.0/28
206.146.137.0/28
206.146.138.0/28
206.146.139.0/28
206.146.141.0/28
```
Do not add the separate RTP/media ranges as inbound authentication addresses.
## Validate
Call the assigned DID externally and confirm a new inbound record, the expected assistant, and two-way audio. If signaling arrives but audio fails, investigate media separately instead of widening the signaling allowlist.
Source: [Sinch Elastic SIP Trunking networks](https://community.sinch.com/t5/Elastic-SIP-Trunking/Getting-started-with-Elastic-SIP-Trunking/ta-p/11380). Accessed 22 August 2026.
# Telnyx SIP trunk
Source: https://docs.famulor.io/telephony/providers/telnyx
Configure a Telnyx FQDN connection and its regional signaling sources
## Recommended profile
Create a Telnyx **FQDN connection** whose primary destination is the platform SIP FQDN. Assign the DID, and configure Telnyx ANI and DNIS number formats as `+E.164`.
On the platform, use the exact `+E.164` DID and **[Provider source IPs](/telephony/sip-trunks#inbound-receiving-calls)**. Telnyx credentials or IP authentication for calls into Telnyx are outbound settings; they do not document digest authentication from Telnyx to an arbitrary FQDN destination.
Allow both signaling addresses for the connection's selected inbound region:
| Region | Sources |
| ----------- | ------------------------------------------ |
| US | `192.76.120.10/32`, `64.16.250.10/32` |
| Europe | `185.246.41.140/32`, `185.246.41.141/32` |
| Australia | `103.115.244.145/32`, `103.115.244.146/32` |
| Canada | `192.76.120.31/32`, `64.16.250.13/32` |
| Middle East | `185.246.42.128/32`, `185.246.42.129/32` |
| Asia (beta) | `103.115.244.158/32`, `103.115.244.159/32` |
Use TCP 5060 for standard signaling; Telnyx also supports TLS 5061. Re-open the Telnyx live network page before saving because regional addresses can change.
## Troubleshooting
**Outbound calls fail with a 403 and "Dialed number is not included in whitelisted countries"** — the connection's Outbound Voice Profile restricts destinations by default. Open that profile's **Allowed Destinations** and add the countries you need. A connection with the right FQDN and IP allowlist still won't complete outbound calls to a country that isn't explicitly enabled there.
## Validate
Place one external inbound call and verify the call record, assigned assistant, and two-way audio. If it fails, check the connection's inbound region and the DID format before widening any address range.
Sources: [Telnyx authentication directions](https://developers.telnyx.com/docs/voice/sip-trunking/authentication/credential-types), [Telnyx live SIP network data](https://sip.telnyx.com/?lang=portal). Accessed 22 August 2026.
# Twilio Elastic SIP Trunking
Source: https://docs.famulor.io/telephony/providers/twilio
Configure Twilio origination to the platform and allow Twilio signaling CIDRs
## Recommended profile
1. In Twilio Elastic SIP Trunking, add an Origination SIP URI in the form `sip:;transport=tcp` and assign the DID to the trunk.
2. In the platform, enter the exact `+E.164` DID and select **[Provider source IPs](/telephony/sip-trunks#inbound-receiving-calls)**.
3. Do **not** use platform inbound digest. Twilio credential lists authenticate customer-to-Twilio termination, not Twilio-to-platform origination.
Allow every Twilio regional signaling CIDR for failover:
```text theme={null}
54.172.60.0/30
54.244.51.0/30
54.171.127.192/30
35.156.191.128/30
54.65.63.192/30
54.169.127.128/30
54.252.254.64/30
177.71.206.192/30
```
Twilio documents UDP/TCP signaling on port 5060 and TLS on 5061. The list above is for signaling; do not substitute Twilio media ranges.
For outbound calls, configure the Twilio termination domain and a Twilio credential list separately. A Twilio termination host normally follows `.pstn.twilio.com`; do not paste an Origination SIP URI into that field.
## Troubleshooting
**Outbound calls don't connect, but inbound works** — check the Termination SIP URI first for a stray space or a copy-paste error; it must be exact (`.pstn.twilio.com`), with no extra whitespace. Twilio also publishes localized termination URIs — use the one closest to your own region rather than the default global host before you start changing credentials.
**International calls fail or are rejected** — Twilio blocks international dialing by default. In the Twilio console, search "geo" to find **Voice → Geographic Permissions → Elastic SIP Trunking**, and enable the destination countries you need.
## Validate
Call the Twilio DID externally. Confirm a new inbound record, correct assistant routing, and two-way audio. A Twilio call log without a corresponding platform inbound call is not proof of delivery.
Sources: [Twilio signaling IPs](https://www.twilio.com/docs/sip-trunking/ip-addresses), [Twilio Elastic SIP Trunking](https://www.twilio.com/docs/sip-trunking). Accessed 22 August 2026.
# Vonage SIP Trunking
Source: https://docs.famulor.io/telephony/providers/vonage
Configure Vonage SIP URI delivery with the official source subnets
## Recommended profile
Configure the inbound Vonage route to the platform SIP FQDN. Keep the exact DID in `+E.164` and choose **[Provider source IPs](/telephony/sip-trunks#inbound-receiving-calls)** in the platform. Vonage documents digest/ACL controls for customer-to-Vonage traffic, not digest from Vonage toward the customer SIP URI.
Vonage recommends allowing both primary platform subnets because SIP traffic can originate from either:
```text theme={null}
216.147.0.0/18
168.100.64.0/18
```
Vonage documents UDP/TCP on 5060 and TLS on 5061. Use the same transport at both ends and keep RTP/media rules separate from SIP signaling authentication. Recipient and caller identity use E.164.
Vonage does not support SIP REFER, so a cold transfer fails over a Vonage trunk. Configure any assistant transfer on this trunk as a warm transfer instead.
## Validate
Call the routed DID externally and confirm a new inbound platform call, the assigned assistant, and two-way audio. If no inbound record appears, verify the Vonage destination URI and source subnet before changing number matching.
Sources: [Vonage SIP dashboard](https://developer.vonage.com/en/sip/sip-dashboard), [Vonage technical details](https://developer.vonage.com/en/sip/technical-details), [Vonage allowlist](https://api.support.vonage.com/hc/en-us/articles/360035471331-Which-IP-addresses-should-I-allow-when-using-Communication-APIs-and-SIP-Trunking). Accessed 22 August 2026.
# Wavix SIP trunk
Source: https://docs.famulor.io/telephony/providers/wavix
Route a Wavix DID to the platform using the current gateway allowlist
## Recommended profile
Configure the Wavix DID destination as `[did]@;transport=tcp`. In the platform, enter the exact DID in `+E.164` and choose **[Provider source IPs](/telephony/sip-trunks#inbound-receiving-calls)**. Credentials described for platform-to-Wavix calls are outbound credentials, not proof of digest on inbound FQDN delivery.
Wavix's official integration guide showed these gateways on 22 August 2026:
```text theme={null}
95.211.82.14/32
209.58.144.243/32
173.234.106.26/32
23.108.101.90/32
```
Wavix says the current complete gateway list at the bottom of the customer portal's **Trunks** page is authoritative. Compare the portal list before every new setup; do not assume this dated snapshot is permanent.
## Validate
Call the Wavix DID from an external phone and verify the inbound call record, assigned assistant, and two-way audio. If no call appears, compare the current portal gateway list and the DID sent in the Request-URI before changing the trunk.
Source: [Wavix gateway and portal guidance](https://docs.wavix.com/sip-trunking/guides/vapi). Accessed 22 August 2026.
# BYO SIP trunk
Source: https://docs.famulor.io/telephony/sip-trunks
Connect your own SIP provider and use your existing numbers
Already have numbers and a SIP provider (Twilio, Telnyx, Plivo, Easybell, or any standards-compliant trunk)? Connect them directly without porting anything.
For provider-specific FQDN direction, inbound authentication, and signaling allowlists, open the [SIP provider guides](/telephony/providers/overview).
## Setup checklist
1. **Copy the platform SIP URI** from **Settings → Numbers → Add a number → Add SIP integration** (or Carrier import). Pick a **SIP region** (default: global) so inbound signaling terminates where you need it (e.g. EU).
2. At your provider, set that URI as the **origination / forwarding destination** for your numbers.
3. Create the trunk in the platform (form below) — inbound auth + outbound termination.
4. Assign numbers to assistants and test inbound, then one outbound test call.
## Trunk type
| Type | When to use | Numbers |
| ---------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Phone number (DID)** | Most carriers (recommended) | One E.164 DID on the trunk; listed under **Numbers** |
| **SIP Extension** | Carrier requires national or extension-style outbound caller ID | One explicit **Primary DID** is required for inbound matching — full E.164 (`+…`) **or** national digits without country code (e.g. `0741926265`). This is not a wildcard; national-only primaries are not listed under Numbers |
## Inbound (receiving calls)
* **Your phone number (DID)** — public E.164 customers dial; must match what the carrier forwards to the platform SIP URI.
* **Inbound authentication**
* **SIP username/password** — only when the carrier explicitly sends digest credentials to the forwarding destination.
* **Provider source IPs** — use when the carrier forwards to the platform FQDN without downstream digest and publishes stable SIP-signaling IPs/CIDRs. Do not use media ranges or overly wide networks.
* At the provider: forward / originate to the platform SIP URI you copied.
Incoming calls are matched to the assistant you assign, exactly like marketplace numbers.
## Outbound (calling out)
* **Termination address** — provider SIP host only (e.g. `sip.telnyx.com`). No `sip:` prefix, no port.
* **Transport** — `AUTO` (recommended), `UDP`, `TCP`, or `TLS`. Secure trunking always uses TLS.
* **Outbound region** — where the platform originates the call. Prefer **Automatic**, or the country closest to your customers / carrier POP.
* **Outbound calling number format** — how the FROM number is sent to the carrier. Must match the carrier’s setting (e.g. Telnyx Origination Number Format):
* International with `+` (recommended for most)
* International without `+`
* National (no country code)
* **Credentials**
* **Shared** (recommended) — one username/password for inbound and outbound.
* **Separate** — distinct inbound vs outbound secrets when the carrier requires it.
* **Outbound authentication** — username/password (recommended). The platform has **no static outbound IPs**, so carrier IP allowlists usually fail. Use “no credentials” only if the carrier explicitly allows unauthenticated outbound.
Outbound calls and [campaigns](/campaigns/overview) can then use your trunk and your caller IDs.
## Advanced
Expand **Advanced** when creating or editing a BYO trunk:
| Setting | Meaning | Recommendation |
| ------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| **Secure trunking (TLS + SRTP)** | Encrypted signaling + media | Enable when the carrier supports Secure Trunking / TLS+SRTP |
| **Media encryption** | Allow (prefer SRTP) or Require SRTP | Allow unless compliance requires Require |
| **Custom outbound headers** | X-\* on outbound INVITEs (max 10) | Empty unless carrier docs require a header |
| **Inbound headers (200 OK)** | Custom X-\* in the SIP 200 OK | Usually empty |
| **Header → attribute maps** | Make selected SIP header values available to assistants and tools | Only if you need carrier metadata |
| **Include SIP headers as attributes** | None / all X-\* / all headers | **None** (map only what you need) |
| **Media codecs** | Extra SDP codecs (PCMU, PCMA, G.722, AMR-WB) | Leave platform defaults; add AMR-WB only if required. Avoid “Only listed codecs” unless you know peer codecs |
| **Media / ringing timeouts** | Optional overrides (seconds) | Leave empty (platform defaults) unless troubleshooting |
**HD Voice (G.722):** enable on the **Telnyx** connection/codec settings when needed (supported with Telnyx, not Twilio).
## Editing an existing trunk
Existing trunks are edited from **Numbers → Configure → Carrier Settings** (not from a separate trunk list on Add SIP integration).
## EU routing
For EU customers, select the **EU SIP region** when creating the connection. Consult your agreement and data-processing documentation for the applicable regional commitments.
## Limits and behavior
* E.164 numbers on BYO trunks count against the same plan number allowance as purchased numbers.
* Calls over your own trunk avoid the platform's per-destination carrier surcharge — your provider bills termination directly. Plan minutes are still consumed; see [billing](/billing/minutes).
* Assistant features such as flows, warm transfer, and recording work identically on BYO trunks.
## Troubleshooting
**Outbound calls fail or don't connect** — check the termination host, transport, and credentials against your provider's documentation first: a wrong transport (UDP vs. TLS), or an extra `sip:` prefix or port on the termination address, is the most common cause. Then compare the outbound calling number format and the codec settings with what the provider expects. Change one setting at a time and place a single test call after each, so **History** shows you which change fixed it.
**Inbound calls don't reach the assistant** — the provider must send calls to the platform's SIP **FQDN**, never to a raw IP address; sending to an IP is the most common inbound failure. With Provider source IPs, confirm every current signaling IP or CIDR is entered — a stale or incomplete list drops calls silently. Then confirm the DID matches exactly what the provider sends: a SIP Extension trunk also needs its Primary DID set, since it isn't a wildcard.
**Call transfers over SIP REFER fail** — confirm the destination provider actually supports SIP REFER; not every carrier does, and that's the most common cause. If one URI format fails, try the alternatives in order: with the port (`sip:+1234567890@sip-server:5060`), without the port, then a bare `sip:+1234567890`. Rule out the destination itself as well — check that the target number is reachable and not blocked before assuming the trunk is at fault. When a transfer was attempted and failed, the call's event log holds `call_transfer_failed` or `warm_transfer_failed`; see [Inbound & outbound calls](/telephony/inbound-outbound#failure-guidance) for the shared failure shape.
Test inbound and outbound independently — one working does not confirm the other. Still stuck? Contact support with the call ID, the exact trunk configuration, and, for transfer issues, the SIP URI format you tried.
## API and MCP
Create and manage trunks via the Public API (`POST /api/v1/sip-trunks` and related endpoints in the API reference), or with the MCP tools `create_sip_trunk`, `list_sip_trunks`, `get_sip_trunk`, and `delete_sip_trunk`. Both surfaces support the same customer-facing settings as the UI, and passwords are never returned.
Test inbound first: call one of your numbers and check it appears in **History** with the right assistant. Then verify outbound with a single test call before wiring the trunk into campaigns.
# WhatsApp Voice
Source: https://docs.famulor.io/telephony/whatsapp-voice
How WhatsApp calling works on the platform — setup and product UX
Outbound WhatsApp calling is a workspace-gated Beta capability, is only
available in supported regions, and requires explicit permission from the
recipient. Multi-channel campaigns request permission automatically, show
the lead as **Awaiting permission**, and dial only after permission is granted.
A decline or expiry ends that delivery attempt.
The same assistant that answers phone calls can also answer WhatsApp voice calls. Campaign calls receive the lead information and mapped variables configured in the campaign.
Product setup (credentials, webhook, toggles, templates): **Settings → Channels → WhatsApp** — see [WhatsApp (Text + Voice)](/channels/whatsapp).
Text and voice use the same WhatsApp connection. For manual setup, subscribe the displayed webhook URL to both **messages** and **calls**.
## What the end user sees
1. Customer taps **call** on your WhatsApp Business number (or answers an outbound call).
2. Normal WhatsApp call UI (ringing → connected).
3. Your assistant speaks as it does on a phone call.
4. After hang-up, the call appears in History with its analysis and usage.
There is no custom in-app WhatsApp dialer for the customer — they stay in WhatsApp.
## What workspace admins will see (product)
**Settings → Channels → WhatsApp**:
1. Connect Meta credentials (Phone Number ID + permanent System User token + app secret + verify token + WABA ID), or use **Connect with Meta**.
2. Assign an assistant.
3. Copy the displayed webhook URL for messages, calls, and template-status updates.
4. Enable voice inbound / outbound toggles (outbound is region-dependent + Meta user permission).
5. Optional: place a test WhatsApp call from the same panel.
Public API: `POST /api/v1/calls/whatsapp-outbound`.
## Apps / accounts you need
1. [Meta Developer](https://developers.facebook.com/) account.
2. WhatsApp Business Account (WABA) with a business phone number.
3. **Voice calling** enabled on that number (Cloud API v23/v24).
4. Meta app with WhatsApp product + permanent **System User** access token (or Embedded Signup).
## Meta setup (step by step)
1. Create / open a Meta app → add **WhatsApp**.
2. Under WhatsApp → API Setup, note:
* **Phone number ID**
* **Access token** (use a long-lived System User token in production)
3. WhatsApp → Configuration → Webhooks:
* Callback URL: copy the connector-specific URL shown in Settings
* Verify token: use the value shown for the connector
* Subscribe at least to **`calls`** (and **`messages`** for text)
* Use API version **v23.0** or **v24.0** consistently
4. Enable call permissions:
* Inbound: configure available call hours (user-initiated calls)
* Outbound: only in supported regions + explicit user permission
## Place an outbound call
Start an outbound WhatsApp call from the sender panel, `POST /api/v1/calls/whatsapp-outbound`, or the `start_whatsapp_outbound_call` MCP tool. Meta supports business-initiated calling only in eligible regions and after the recipient has granted permission.
## Related
* [WhatsApp (Text + Voice)](/channels/whatsapp)
* [Messaging channels](/channels/messaging)
* [Phone numbers](/telephony/phone-numbers)
* [Campaigns](/campaigns/overview)
# Web widget
Source: https://docs.famulor.io/web-widget
Embed your assistant as a voice and chat widget on any website
The web widget puts your assistant on your website: visitors click a button and **talk to the assistant in the browser** (no phone or app required) or type in a **chat** with the same assistant. The widget is available when included in your plan.
## Voice + chat, one assistant
* **Voice** — a click starts a live voice conversation using the assistant's full configuration: engine mode, voice, knowledge base, tools, guardrails. During the session, the panel keeps the presence visual large and shows the latest spoken words in small caption groups; the full transcript remains available in [History](/monitoring/history), where web calls use direction `web`.
* **Chat** — the same assistant, prompts, and knowledge base in text form, for visitors who can't or won't speak.
Because both channels share one assistant configuration, you maintain behavior in one place.
## Visitor languages
All standard widget controls, form prompts, verification screens and error messages support 86 languages. The visitor’s preferred browser language is used first. Country detection supplies a fallback; English is used when no supported language can be determined. Right-to-left languages use a matching layout.
Your own greetings, assistant names, edited field labels and other custom text stay exactly as written. Conversation content is not translated by the widget. The security challenge uses its own supported languages.
## Embedding
Create a widget under **Settings → Channels → Web Widget**, then paste a snippet from the editor. Choose **Display**:
The default — a corner launcher bubble. Position and Initial state apply. Prefer the **script** loader (it sets `allow="microphone"` on the iframe automatically):
```html theme={null}
```
The widget sits in your page flow (no launcher). Prefer the web component or iframe snippet (portrait sizing included for avatar cards):
```html theme={null}
```
Or mount into a target node: `data-ouraicalling-widget-target="#ouraicalling-assistant"` on the script tag.
See the embed panel for ready-made HTML, React, and Markdown snippets. New snippets use the neutral Ouraicalling widget API; legacy `data-famulor-key` snippets remain supported. On white-label domains the widget is served from **your tenant domain** with your branding.
## Allowed origins
List the website(s) that may embed the widget (exact origins like `https://example.com`, or subdomain wildcards like `*.example.com`). Localhost is supported for development. Origins are **optional** when creating or saving a widget.
* An empty allowlist does **not** mean “open to any site”: foreign origins are blocked. Only the platform domain itself stays allowed so the in-app live preview keeps working.
* Add every website host that will load the snippet before going live. If the widget fails to load on a customer site, check Allowed origins first.
## Customization
* **Display** — **Floating** (corner launcher) or **Inline** (in-page embed). Position and Initial state only apply to Floating.
* **Colors and branding** — launcher color, panel accent, logo; tenant branding applies automatically on white-label domains.
* **Position** — corner placement of the floating launcher (hidden for Inline).
* **Modes** — voice-only, chat-only, or both.
* **Voice presence** — classic audio visualizer, or a **virtual AI avatar** (see below).
* **Launcher icon** — Milian, Chat bubbles, Question mark, Smiley face, Team, or Hand wave. Applies to chat-only, voice-only, and both.
* **Launcher label** — presets (**No text** default; Help, Ask anything, Assistance, Support, Live Chat, Need help?) translated from the visitor’s browser language. Avatar-only still uses optional custom launcher text for the glass CTA.
* **Texts** — welcome message, AI disclosure, privacy notice.
* **Pre-chat form** — optional form before chat or voice starts (see below).
## Virtual AI avatar
Virtual avatars require the AI Avatar feature. In the widget editor, set **Voice presence** to **AI avatar** and pick an avatar.
* **Layouts**
* **Avatar only (full-bleed)** — compact card focused on the face. Floating widgets can start **Expanded** or **Minimized**; Inline always shows the card in place.
* **Avatar + chat** — avatar presence with the classic chat/voice panel chrome.
* **Billing** — voice sessions bill the normal talk-minute rate, plus the **Web widget virtual avatar** surcharge per minute while a virtual avatar is active; plain text chat messages sent and received bill credits per message at the workspace's **Web chat (sent)** / **Web chat (received)** rate. Current rates are on the [Usage page](https://app.famulor.io/usage); see also [How usage is billed](/billing/minutes).
* Without AI Avatar access, the editor shows an upgrade option and the API rejects enabling avatar presence.
## Pre-chat form
Open the widget in the editor, find **Pre-chat form**, and turn on **Enable**. Visitors then fill in fields before the session starts.
* **Suggestions** come from contact fields (name, email, phone), the selected assistant’s input variables, and workspace Audience attributes. You can also add custom keys.
* Submitted values become call **input variables** (`{{variable_key}}`), update the Audience lead when identity fields are present, and appear in **History** under Pre-chat form / Input variables.
* Required fields are validated before a visitor can start a session.
## Things to check before going live
List every site that will embed the widget. Without origins, third-party hosts cannot load config or mint tokens.
The widget uses the same web-call path as the assistant editor's test call — if that sounds right, the widget will too.
Browsers require HTTPS for microphone access. The host page must not block microphone via `Permissions-Policy`. Script/web-component embeds set `allow="microphone"` on the iframe automatically.
Voice conversations are processed like calls (transcripts, optional recording with consent flow). Mention the widget in your privacy policy.
## Troubleshooting
Confirm the embed snippet sits before the closing `