# Create account connection
Source: https://docs.fluents.ai/api-reference/account_connections/create-account-connection
openapi.yml post /v1/account_connections/create
# Get account connection
Source: https://docs.fluents.ai/api-reference/account_connections/get-account-connection
openapi.yml get /v1/account_connections
# List account connections
Source: https://docs.fluents.ai/api-reference/account_connections/list-account-connections
openapi.yml get /v1/account_connections/list
# Update account connection
Source: https://docs.fluents.ai/api-reference/account_connections/update-account-connection
openapi.yml post /v1/account_connections/update
# Create action
Source: https://docs.fluents.ai/api-reference/actions/create-action
openapi.yml post /v1/actions/create
# Get action
Source: https://docs.fluents.ai/api-reference/actions/get-action
openapi.yml get /v1/actions
# List actions
Source: https://docs.fluents.ai/api-reference/actions/list-actions
openapi.yml get /v1/actions/list
# Update action
Source: https://docs.fluents.ai/api-reference/actions/update-action
openapi.yml post /v1/actions/update
# Create agent
Source: https://docs.fluents.ai/api-reference/agents/create-agent
openapi.yml post /v1/agents/create
# Get agent
Source: https://docs.fluents.ai/api-reference/agents/get-agent
openapi.yml get /v1/agents
# List agents
Source: https://docs.fluents.ai/api-reference/agents/list-agents
openapi.yml get /v1/agents/list
# Update agent
Source: https://docs.fluents.ai/api-reference/agents/update-agent
openapi.yml post /v1/agents/update
# Create call
Source: https://docs.fluents.ai/api-reference/calls/create-call
openapi.yml post /v1/calls/create
# End call
Source: https://docs.fluents.ai/api-reference/calls/end-call
openapi.yml post /v1/calls/end
# Create call feedback
Source: https://docs.fluents.ai/api-reference/calls/feedbacks/create-call-feedback
openapi.yml post /v1/calls/{call_id}/feedbacks
# Delete call feedback
Source: https://docs.fluents.ai/api-reference/calls/feedbacks/delete-call-feedback
openapi.yml delete /v1/calls/{call_id}/feedbacks/{id}
# Get call feedback
Source: https://docs.fluents.ai/api-reference/calls/feedbacks/get-call-feedback
openapi.yml get /v1/calls/{call_id}/feedbacks/{id}
# List call feedbacks
Source: https://docs.fluents.ai/api-reference/calls/feedbacks/list-call-feedbacks
openapi.yml get /v1/calls/{call_id}/feedbacks
# Update call feedback
Source: https://docs.fluents.ai/api-reference/calls/feedbacks/update-call-feedback
openapi.yml patch /v1/calls/{call_id}/feedbacks/{id}
# Get call
Source: https://docs.fluents.ai/api-reference/calls/get-call
openapi.yml get /v1/calls
# Get call recording
Source: https://docs.fluents.ai/api-reference/calls/get-call-recording
openapi.yml get /v1/calls/{id}/recording_url
# Get recording
Source: https://docs.fluents.ai/api-reference/calls/get-recording
openapi.yml get /v1/calls/recording
# List calls
Source: https://docs.fluents.ai/api-reference/calls/list-calls
openapi.yml get /v1/calls/list
# Add multiple phone numbers to DNC list
Source: https://docs.fluents.ai/api-reference/dnc_numbers/bulk-add-dnc-numbers
openapi.yml post /v1/dnc_numbers/bulk
Add multiple phone numbers to the Do Not Call list for a specific user in a single request. Maximum 1000 phone numbers per request.
# Add a phone number to DNC list
Source: https://docs.fluents.ai/api-reference/dnc_numbers/create-dnc-number
openapi.yml post /v1/dnc_numbers/create
Add a phone number to the Do Not Call list for a specific user.
# Remove a phone number from DNC list
Source: https://docs.fluents.ai/api-reference/dnc_numbers/delete-dnc-number
openapi.yml delete /v1/dnc_numbers/{id}
Remove a phone number from the Do Not Call list for a specific user.
# Get DNC numbers
Source: https://docs.fluents.ai/api-reference/dnc_numbers/list-dnc-numbers
openapi.yml get /v1/dnc_numbers/list
Retrieve DNC numbers with filtering by type (global or user-specific) and pagination.
# Create knowledge base
Source: https://docs.fluents.ai/api-reference/knowledge_bases/create-knowledge-base
openapi.yml post /v1/knowledge_bases
# Delete knowledge base
Source: https://docs.fluents.ai/api-reference/knowledge_bases/delete-knowledge-base
openapi.yml delete /v1/knowledge_bases/{id}
# Delete knowledge base file
Source: https://docs.fluents.ai/api-reference/knowledge_bases/delete-knowledge-base-file
openapi.yml delete /v1/knowledge_bases/{kbId}/files/{fileId}
# Get knowledge base
Source: https://docs.fluents.ai/api-reference/knowledge_bases/get-knowledge-base
openapi.yml get /v1/knowledge_bases/{id}
# Get knowledge base file
Source: https://docs.fluents.ai/api-reference/knowledge_bases/get-knowledge-base-file
openapi.yml get /v1/knowledge_bases/{kbId}/files/{fileId}
# List knowledge base files
Source: https://docs.fluents.ai/api-reference/knowledge_bases/list-knowledge-base-files
openapi.yml get /v1/knowledge_bases/{kbId}/files
# List knowledge bases
Source: https://docs.fluents.ai/api-reference/knowledge_bases/list-knowledge-bases
openapi.yml get /v1/knowledge_bases
# Upload knowledge base file
Source: https://docs.fluents.ai/api-reference/knowledge_bases/upload-knowledge-base-file
openapi.yml post /v1/knowledge_bases/{kbId}/files
# Create message
Source: https://docs.fluents.ai/api-reference/messages/create-message
openapi.yml post /v1/messages
# List messages
Source: https://docs.fluents.ai/api-reference/messages/list-messages
openapi.yml get /v1/messages
# Activate number
Source: https://docs.fluents.ai/api-reference/numbers/activate-number
openapi.yml post /v1/numbers/activate
# Buy number
Source: https://docs.fluents.ai/api-reference/numbers/buy-number
openapi.yml post /v1/numbers/buy
# Cancel number
Source: https://docs.fluents.ai/api-reference/numbers/cancel-number
openapi.yml post /v1/numbers/cancel
# Detach number
Source: https://docs.fluents.ai/api-reference/numbers/detach-number
openapi.yml post /v1/numbers/detach
# Get number
Source: https://docs.fluents.ai/api-reference/numbers/get-number
openapi.yml get /v1/numbers
# Get number tags
Source: https://docs.fluents.ai/api-reference/numbers/get-number-tags
openapi.yml get /v1/numbers/tags
# Link number
Source: https://docs.fluents.ai/api-reference/numbers/link-number
openapi.yml post /v1/numbers/link
# List available numbers
Source: https://docs.fluents.ai/api-reference/numbers/list-available-numbers
openapi.yml get /v1/numbers/available
# List numbers
Source: https://docs.fluents.ai/api-reference/numbers/list-numbers
openapi.yml get /v1/numbers/list
# Update number
Source: https://docs.fluents.ai/api-reference/numbers/update-number
openapi.yml post /v1/numbers/update
# Create prompt
Source: https://docs.fluents.ai/api-reference/prompts/create-prompt
openapi.yml post /v1/prompts/create
# Get prompt
Source: https://docs.fluents.ai/api-reference/prompts/get-prompt
openapi.yml get /v1/prompts
# List prompts
Source: https://docs.fluents.ai/api-reference/prompts/list-prompts
openapi.yml get /v1/prompts/list
# Update prompt
Source: https://docs.fluents.ai/api-reference/prompts/update-prompt
openapi.yml post /v1/prompts/update
# Run simulation
Source: https://docs.fluents.ai/api-reference/simulation/run-simulation
openapi.yml post /v1/simulation/run
# Create tag
Source: https://docs.fluents.ai/api-reference/tags/create-tag
openapi.yml post /v1/tags
# Delete tag
Source: https://docs.fluents.ai/api-reference/tags/delete-tag
openapi.yml delete /v1/tags/{id}
# Get tag
Source: https://docs.fluents.ai/api-reference/tags/get-tag
openapi.yml get /v1/tags/{id}
# List tags
Source: https://docs.fluents.ai/api-reference/tags/list-tags
openapi.yml get /v1/tags
# Update tag
Source: https://docs.fluents.ai/api-reference/tags/update-tag
openapi.yml patch /v1/tags/{id}
# Create transcriber
Source: https://docs.fluents.ai/api-reference/transcribers/create-transcriber
openapi.yml post /v1/transcribers/create
# Delete transcriber
Source: https://docs.fluents.ai/api-reference/transcribers/delete-transcriber
openapi.yml delete /v1/transcribers/{id}
# Get transcriber
Source: https://docs.fluents.ai/api-reference/transcribers/get-transcriber
openapi.yml get /v1/transcribers
# List transcribers
Source: https://docs.fluents.ai/api-reference/transcribers/list-transcribers
openapi.yml get /v1/transcribers/list
# Update transcriber
Source: https://docs.fluents.ai/api-reference/transcribers/update-transcriber
openapi.yml post /v1/transcribers/update
# Create voice
Source: https://docs.fluents.ai/api-reference/voices/create-voice
openapi.yml post /v1/voices/create
# Get voice
Source: https://docs.fluents.ai/api-reference/voices/get-voice
openapi.yml get /v1/voices
# List voices
Source: https://docs.fluents.ai/api-reference/voices/list-voices
openapi.yml get /v1/voices/list
# Update voice
Source: https://docs.fluents.ai/api-reference/voices/update-voice
openapi.yml post /v1/voices/update
# Create webhook
Source: https://docs.fluents.ai/api-reference/webhooks/create-webhook
openapi.yml post /v1/webhooks/create
# Get webhook
Source: https://docs.fluents.ai/api-reference/webhooks/get-webhook
openapi.yml get /v1/webhooks
# List webhooks
Source: https://docs.fluents.ai/api-reference/webhooks/list-webhooks
openapi.yml get /v1/webhooks/list
# Update webhook
Source: https://docs.fluents.ai/api-reference/webhooks/update-webhook
openapi.yml post /v1/webhooks/update
# How a call runs
Source: https://docs.fluents.ai/product/concepts/agent/advanced
What happens between the caller finishing a sentence and the agent replying, and why that gap is the thing you tune.
A voice agent is three systems in a chain. Understanding the chain explains most of
what feels wrong on a bad call.
***
## The chain
**Speech to text** turns what the caller said into words.
**A language model** decides what to say back, following your prompt.
**Text to speech** turns that reply into audio.
Each link takes time, and the caller experiences the total as the pause before the
agent answers. Every provider choice you make is a trade between how good a link is
and how fast.
***
## Latency is the thing callers notice
People forgive an agent that says something slightly wrong. They do not forgive an
agent that leaves a two second silence, because silence on a phone call reads as a
dropped connection.
Fluents records timings per link on every call, so when an agent feels sluggish you
can see which part of the chain is responsible rather than guessing. See
**[Calls](/product/features/call)**.
If an agent has to do something slow, such as calling your own systems mid
conversation, let it say something first. A filled pause is fine. An unexplained one
is not.
***
## Knowing when the caller has finished
The agent has to decide when a caller has stopped speaking rather than merely paused.
Too eager and it interrupts. Too patient and it feels unresponsive.
There is a related question of what to do when nobody says anything at all. The agent
waits, checks in, and eventually ends the call rather than holding an open line
forever.
Both are tunable. See **[Agents](/product/features/agent)**.
***
## Calls have a ceiling
A call has a maximum length, so a conversation that goes nowhere cannot run
indefinitely and bill you for it.
Separately, each environment has a **concurrency limit**, which is how many calls can
run at once. This is the constraint people hit and misdiagnose most often. A campaign
that appears to be dialing slowly is usually queued against this number rather than
malfunctioning. See **[Settings](/product/features/account/settings)**.
***
## Models are a choice, not a given
You can change which language model runs the conversation. Larger models reason better
about complicated instructions. Smaller ones reply faster.
For most phone conversations, faster wins. The reasoning demands of a well written
prompt are usually modest, and the latency cost of a large model is paid on every
single turn.
***
## Recording and privacy
Recording is a setting, not a default, and it interacts with your obligations rather
than replacing them. Compliance modes restrict what is retained.
Compliance settings restrict what Fluents stores. They do not tell you what you are
legally required to do, and they are not a substitute for consent where consent is
required.
***
## Where to go next
* **[Agents](/product/features/agent)** for the settings themselves.
* **[Calls](/product/features/call)** for per-call timings.
* **[What happens after a call](./post-call)** for what the platform does once the
conversation ends.
# What the agent says
Source: https://docs.fluents.ai/product/concepts/agent/basic
How the prompt, the opening line, the voice and the skills combine into a conversation.
Four things shape what a caller actually hears. They interact, which is why changing
one and being surprised is so common.
***
## The opening line
The first thing the agent says is set separately from the prompt, and it matters out
of proportion to its length.
On an outbound call it decides whether the person stays on the line. On an inbound
call it sets what they think they are allowed to ask for.
It can include values from the call's context, such as a name, so the same line reads
differently per contact.
If you change one thing about an underperforming agent, change this. It is one
sentence and it gates everything after it.
***
## The prompt
The prompt is the agent's standing instructions. It is read before every conversation
and it is where behaviour actually lives.
Some things that hold true regardless of what you are building:
**Simple instructions beat complex ones.** A short prompt that the agent follows is
worth more than a thorough one it approximates.
**Structure helps.** A long prompt split into sections is followed more reliably than
the same content as prose.
**Examples beat description.** Showing the agent a good exchange does more than
describing one.
**Write for speech.** The agent reads this aloud. Unusual words and proper nouns need
spelling out phonetically, or they come out mangled.
Prompts can be saved and reused across agents. See
**[Prompts](/product/features/prompts)**.
***
## The voice
A voice has a provider, and usually a speaking speed. Language is set separately, on
the agent. Voices differ in more than timbre. Some handle interruption and pacing better than others, and the only reliable
test is hearing one read your own opening line rather than a sample.
You can also bring in a voice from a provider you already use. See
**[Voices](/product/features/voice)**.
***
## Skills
Skills are the difference between an agent that talks and an agent that does things.
Each one adds an ability and, usually, some instructions of its own that the agent
follows alongside your prompt.
They cover roughly four jobs:
* **Ending the conversation well**, by hanging up cleanly or agreeing a callback.
* **Getting to the right person**, by transferring, handling a screener, or working
through a phone menu.
* **Doing something concrete**, such as booking an appointment or sending a message.
* **Knowing things**, by searching content you have stored.
Skills add instructions to the agent, so switching on several at once can crowd your
prompt. If behaviour changes after adding a skill, that is why. Add them one at a
time and test between.
See **[Agents](/product/features/agent)** for the full list and their settings.
***
## Context
A call can start with values already known, such as the person's name or an order
number. Those are available to the prompt and to the opening line.
On a campaign they come from your contact list. On a test call you set them by hand.
Personalisation only works when they are actually present, which is why a test call
with empty context sounds worse than the real thing.
***
## Where to go next
* **[How a call runs](./advanced)** for the machinery underneath.
* **[Agents](/product/features/agent)** for every setting.
* **[Testing an agent](/product/features/agent-testing)** for changing a prompt safely.
# What an agent is
Source: https://docs.fluents.ai/product/concepts/agent/intro
The unit everything else in Fluents attaches to, and the four things that decide how it behaves.
An **agent** is a configured voice assistant that holds a phone or browser
conversation. It is the unit everything else attaches to. Numbers ring an agent,
campaigns call through an agent, and every call in your history belongs to one.
You can have as many as you like, and most teams end up with several. One agent per
job works better than one agent that does everything, because the instructions stay
short and the failures stay obvious.
***
## The four things that decide behaviour
**The prompt** is the instructions. It is the largest influence on what the agent
actually does, and most problems are prompt problems.
**The voice** is how it sounds, including language and speaking speed.
**Skills** are discrete abilities you switch on, such as transferring a call, booking
an appointment, or texting during the conversation. An agent without skills can only
talk.
**Settings** are the machinery underneath, such as which models run the conversation
and how long the agent waits before deciding you have stopped speaking.
Everything you configure falls into one of those four.
***
## Inbound and outbound are the same object
There is no separate inbound agent type. An agent becomes inbound when a number points
at it, and outbound when something places a call through it.
The same agent can do both. In practice you usually want different ones, because the
opening line of a call you placed and a call you received have almost nothing in
common.
***
## What an agent produces
Every conversation leaves a record: a transcript, an outcome, timings, and whatever
structured information you asked the agent to extract.
That record is the point. An agent that handles calls but tells you nothing about them
is a call centre with worse reporting.
***
## Where to go next
* **[What the agent says](./basic)** for how the prompt, voice and skills interact.
* **[How a call runs](./advanced)** for what happens between the caller speaking and
the agent replying.
* **[What happens after a call](./post-call)** for turning conversations into data.
* **[Agents](/product/features/agent)** for the settings themselves.
# What happens after a call
Source: https://docs.fluents.ai/product/concepts/agent/post-call
How a conversation becomes structured data you can filter, chart and act on.
A conversation is not useful as a conversation. It becomes useful when it turns into
something you can count.
That is what post-call processing does. When a call ends, the platform reads what
happened and produces structured results.
***
## Insights
An **insight** is a question asked of your calls, answered automatically afterwards.
"Were they interested?" "Which product did they ask about?" "What is their renewal
date?"
Answers can be yes or no, a number, a value from a list you define, or free text.
Insights are only extracted from calls longer than **20 seconds**. Very short calls
produce no insights at all, which is usually right, but it does mean a wall of blank
results is often a wall of hang-ups rather than a fault.
This is the mechanism that turns a pile of transcripts into something you can filter
in **[Calls](/product/features/call)** or chart in **[Reports](/product/features/reports)**.
Write insights as questions you would actually act on. "Was the caller satisfied" is
interesting. "Did they ask for a callback" changes what somebody does next.
***
## Deciding whether a call went well
Insights describe a call. A **result** judges it.
You define what success means as conditions over your insights, and every call is
marked accordingly. Without this, a thousand calls tell you nothing at a glance,
because you have to read them.
Getting this right takes a couple of passes. The first definition of success is
usually too generous.
***
## Acting on the outcome
Once a call is understood, the platform can act:
* **Send a message**, by text or email, to the person or to your team.
* **Update your own systems**, by syncing the outcome to a CRM.
* **Notify anything**, by sending the result to a URL you control.
See **[Post-call](/product/features/post-call)** for setting these up and
**[Webhooks](/product/features/webhook)** for the notification path.
***
## Timing matters more than people expect
Post-call processing is not instant. A call ending and a call being understood are two
different moments, separated by however long the analysis takes.
If you are reacting to calls programmatically, wait for post-call processing to
finish rather than for the call to end. Reading results at the moment the call
stops gets you empty fields.
***
## Where to go next
* **[Post-call](/product/features/post-call)** for configuring insights and results.
* **[Reports](/product/features/reports)** for charting what you extracted.
* **[Webhooks](/product/features/webhook)** for pushing results to your systems.
# How campaigns work
Source: https://docs.fluents.ai/product/concepts/campaigns
When to reach out to a list rather than wait for the phone to ring, and the shapes campaigns usually take.
A **campaign** works a list of contacts for you. Each contact enters, moves through a
sequence you define, and leaves when something conclusive happens.
The word to hold on to is **sequence**. A campaign is not a bulk dial. It is a set of
steps applied to each contact independently, at their own pace.
***
## Campaign or inbound agent
You do not always need a campaign.
Use an **inbound agent alone** when people call you. A support line, an after-hours
line, a main business number.
Use a **campaign** when you are reaching out. Sales outreach, appointment reminders,
payment reminders, re-engagement.
> If your team would otherwise work a call list by hand, you want a campaign.
***
## What a campaign is made of
**Contacts** are who to reach, imported from a file or pulled from a CRM.
**A sequence** is what happens to each of them, one or more steps with waits between.
**An agent** does the talking on each call step.
**A schedule** decides which days and hours contacts may be reached, in a timezone you
set. This is separate from the campaign so several campaigns can share one set of
calling hours.
**A caller number** is what shows up on the recipient's phone.
**Exit criteria** decide when a contact is done and should stop receiving steps.
***
## Contacts leave, and that is the point
The most common surprise is a contact who stops receiving steps.
A contact leaves when they answer, when they ask to stop being contacted, or when
their number turns out to be unreachable. Answering counts as an exit, which is
usually what you want. The campaign existed to reach them, and it did.
If you are expecting a follow-up that never arrives, this is almost always why.
***
## Common shapes
**One call.** Reach a list once. Import contacts, one phone step, business hours. The
right place to start, and often enough.
**Try more than once.** A phone step, a wait of a day, another phone step. Contacts
who answered on the first attempt have already exited, so the second step only reaches
the ones you missed.
**Call, then follow up in writing.** A phone step followed by a message step, for when
a conversation needs something in writing afterwards.
Build the one-step version first even if you know you want three. The failures you
find in a single step are the same failures that would have been three times harder
to see.
***
## Where campaigns touch everything else
Campaigns place calls, so they consume your **concurrency limit**. A campaign that
seems slow is often queued behind that ceiling rather than broken.
They dial from your **numbers**, and calling too hard from one number gets it flagged
as spam by carriers. Pacing exists for this and is worth setting before volume, not
after.
Every call a campaign places lands in your call history like any other, and post-call
processing applies to them in the usual way.
***
## Where to go next
* **[Campaigns](/product/features/campaigns)** for building one.
* **[Campaign schedules](/product/features/campaign-schedules)** for calling hours.
* **[Numbers](/product/features/numbers)** for caller IDs and pacing.
* **[Set up your first campaign](/product/quickstart/first-campaign)** for a worked
example.
# How numbers work
Source: https://docs.fluents.ai/product/concepts/numbers
Why a number belongs to one environment, what it means to point one at an agent, and why spreading traffic matters.
A phone number is what connects your agents to the telephone network. Outbound calls
need one to call from. Inbound calls need one pointed at an agent to arrive at.
***
## Numbers belong to an environment
A number lives in one environment and is invisible everywhere else.
This is deliberate. It means a test environment cannot accidentally dial from your
production caller ID. It is also the reason a number you are certain you bought
appears to be missing, when you are simply looking at a different environment.
***
## Inbound is a pointer
Buying a number does not make anything answer it. A number answers when it points at
an agent.
Until then it can still place outbound calls perfectly well, which is why an unassigned
number is not necessarily a mistake. It just means nothing happens when somebody rings
it.
***
## Outbound is a choice per call
On the way out, the number is the caller ID the recipient sees.
Campaigns can select numbers by tag rather than one at a time, which is what makes
regional caller IDs practical. Tagging by area or purpose when you buy costs seconds
and saves an afternoon later.
***
## One number is not a strategy
Carriers watch how numbers behave. A number that dials fast and often, and rarely gets
answered, starts being labelled as spam on recipients' handsets. Once that happens the
number is worth much less, and it does not recover quickly.
Two things follow.
**Pace each number.** There are controls for how frequently a single number is used,
and they exist precisely to avoid this. Roughly a hundred calls a day per number is a
reasonable ceiling.
**Spread across several.** More volume should mean more numbers, not harder use of
one.
Deliverability is easier to protect than to repair. Set pacing before you scale
volume, not after the first number gets flagged.
***
## Numbers and the do not call list
Numbers your agents must not dial are held separately and apply regardless of which
campaign or agent is calling. Some entries you add. Others are recorded automatically
when someone asks to be left alone.
See **[DNC List](/product/features/dnc-list)**.
***
## Where to go next
* **[Numbers](/product/features/numbers)** for buying, linking and pacing.
* **[Campaigns](/product/features/campaigns)** for choosing caller IDs by tag.
* **[Settings](/product/features/account/settings)** for environment caps.
# How voices work
Source: https://docs.fluents.ai/product/concepts/voices
What actually makes a voice work on a phone call, and why the pleasant one is not always the right one.
The voice is the part of your agent people form an opinion about in the first two
seconds. It is also the setting most often chosen badly, because it is chosen by
listening to a sample rather than to a conversation.
***
## A voice comes from a provider
Fluents does not generate voices itself. It connects to speech providers, each with
its own catalogue and its own character.
You can use the voices already available to you, or bring in one from a provider
account you already have, including a cloned or custom voice.
***
## What matters on a phone call
Sample quality is the least useful signal.
**Speed of first sound** matters more than fidelity. A voice that begins speaking
promptly feels responsive. One that is fractionally richer but slower feels broken,
because the caller reads the gap as a dropped line.
**Behaviour under interruption** matters. People talk over agents constantly. Voices
differ in how gracefully they stop.
**Pacing on numbers and names** matters. Phone numbers, order references and email
addresses are where a voice either helps or forces the caller to ask twice.
Preview with your own opening line, not the provider's sample. A voice reading
marketing copy tells you nothing about the same voice reading your booking reference
back.
***
## Speed belongs to the voice
How fast the agent speaks is saved on the voice itself, not on the agent, and not
every provider supports it. Change to a voice from a provider that does not, and the
control disappears.
Slightly slower than feels natural to you is usually right. You know what the agent is
about to say. The caller does not.
***
## Language
Language is set on the agent, separately from the voice. They should agree.
Mismatching them produces the uncanny result of correct words in the wrong accent and
rhythm.
***
## Where to go next
* **[Voices](/product/features/voice)** for the library and importing.
* **[Agents](/product/features/agent)** for setting voice, language and speed.
* **[Testing an agent](/product/features/agent-testing)** for hearing it in context.
# Get API key
Source: https://docs.fluents.ai/product/features/account/get-api-key
Where the key is, what it is scoped to, and the one thing people get wrong about it.
Every **environment** has its own API key. There is no account-wide key.
***
## Where it is
Open **Settings**, go to the **Environments** tab, and find your environment in the
list. The **API Key** column shows it masked. The eye icon reveals it and the other
icon copies it.
***
## Keys are scoped to one environment
This is the part worth understanding before you start debugging.
A key works only in the environment it came from. It cannot see agents, numbers, calls
or campaigns anywhere else.
The most common API problem is not a broken key. It is the right key pointed at the
wrong environment. Requests succeed and return nothing, because the thing you are
asking about lives somewhere else.
Before assuming a bug, check which environment the key belongs to.
That scoping is deliberate. It means a key you hand to a contractor, or paste into a
staging config, cannot reach production.
***
## Keeping it safe
* **Server side only.** A key in browser code is a published key.
* **One environment per use.** Use your test environment's key for testing.
* **Rotate on exposure.** If a key has been somewhere it should not, replace it.
***
## Where to go next
* Environments, caps and members: **[Settings](./settings)**
* Browser widget tokens, which work differently: **[Web Widget](../widget)**
* Notify your systems instead of polling: **[Webhooks](../webhook)**
# Settings
Source: https://docs.fluents.ai/product/features/account/settings
Organizations, environments and members. Where your API keys and your concurrency and number caps live.
**Settings** covers the organization you are in, the environments inside it, and who
can get at them. Three tabs.
***
## Organizations and environments
An **organization** is your company. An **environment** lives inside it and holds its
own agents, numbers, campaigns and calls.
Nothing crosses between environments. A number bought in one is not available in
another, and calls in one do not appear in another. That is the point of them, and it
is also the thing that catches people out when they cannot find something they made
half an hour ago.
The environment switcher sits at the top of the sidebar.
***
## General
Your **Organization ID** and **Organization name**. Rename it and click **Save**.
Creating a whole separate organization is done from an icon beside the organization
switcher at the top of the page, not from this tab, and it is only available to
reseller accounts. Almost everyone wants a new **environment** instead.
***
## Environments
The list of environments in this organization.
| Column | What it shows |
| - | - |
| **Environment Name** | The name. |
| **API Key** | The environment's key, masked. Reveal it or copy it with the icons. |
| **Limits** | Concurrent calls and number allowance, for example `5 concurrent · 2 numbers`. |
**Create Environment** adds one.
### Editing an environment
Editing opens a dialog with more than the name.
| Setting | What it does |
| - | - |
| **Environment Name** | The name. Required. |
| **Max Concurrent Calls** | How many calls can run at once here. Required. |
| **Max Purchasable Numbers** | The number cap for this environment. |
| **Early Access Program** | Unfinished features. See **[Early Access](../experimental-feature)**. |
| **Enable HIPAA Compliance** | Restricts some features. |
**Max Concurrent Calls** is the limit people hit first and diagnose last. A campaign
that seems to be dialing slowly is usually sitting against this number, not
malfunctioning.
***
## API keys
Each environment has its own key, and it is on this tab. The eye icon reveals it, the
other copies it.
The key is scoped to its environment. A key from your test environment will not
touch production, which is a feature. It also means a request that returns nothing
may be pointed at the wrong environment rather than broken.
See **[Get API key](./get-api-key)**.
***
## Members
Who is in the organization.
| Column | What it shows |
| - | - |
| **Name** | Their name, with **(you)** beside your own. |
| **Email** | Their email. |
| **Role** | What they can do. |
| **Status** | Whether the invitation has been accepted. |
### Invite a member
You need to be an **Admin**.
1. Open **Settings** at the bottom left and go to **Members**.
2. Click **Invite member**.
3. Enter their **Email** and pick a **Role**.
4. Click **Send invitation**.
Their **Status** shows whether they have accepted.
***
## Where to go next
* Get the key and use it: **[Get API key](./get-api-key)**
* Number caps in context: **[Numbers](../numbers)**
* Plans and minutes: **Billing**
# Sign up
Source: https://docs.fluents.ai/product/features/account/sign-up
Create an account, and what you get on the trial before you decide anything.
Create an account at
[platform.fluents.ai/signup](https://platform.fluents.ai/signup).
***
## Creating the account
You can sign up with an email address and a password, or with **Google** or **Apple**.
Signing up with email asks for your full name, your email address and a password.
***
## The trial
New accounts start on a **14 day free trial** with full access. **No credit card is
required** to start it.
For what your trial currently includes, and what each paid plan adds, look at
**Billing** in the platform rather than trusting a figure written in a doc. Plans
change, and the platform is the thing that is right.
***
## What happens next
Your account contains an **organization**, and inside it at least one **environment**.
The environment is where your agents, numbers and calls live.
If you are evaluating, work in a non-production environment from the start. It costs
nothing and it means your experiments never share numbers or call history with
anything real. See **[Settings](./settings)**.
***
## Then build something
Reading about the product is a poor substitute for a fifteen minute build.
* **[Create your first inbound agent](/product/quickstart/first-inbound-agent)** ends
with an agent you can phone.
* **[Create your first outbound agent](/product/quickstart/first-outbound-agent)** ends
with one that calls you.
***
## Where to go next
* **[Settings](./settings)** for organizations, environments and members.
* **[Get API key](./get-api-key)** for programmatic access.
* **[What an agent is](/product/concepts/agent/intro)** for the model behind it all.
# Actions
Source: https://docs.fluents.ai/product/features/actions
Things an agent can do mid-call beyond talking, including calling your own API and getting an answer back before it replies.
**Actions** are tasks an agent performs during a call rather than after it. Transfer
the call, press a key, hang up, or call your own API and use the answer in the next
sentence.
Actions are created once here and then added to any agent.
***
## The two tabs
**Phone Actions** covers things the agent does to the call itself.
**Custom External Actions** covers calling your own API.
***
## The five types
**Create Action** asks which kind you want.
| Type | What it does |
| - | - |
| **End Conversation** | Configure when the agent should end the call. |
| **Transfer Calls** | Configure when the agent should transfer the call to another number. |
| **Use DTMF (Dual Tone Multi-frequency)** | Allow the bot to send keypresses during a call. |
| **Custom Input** | Trigger your own APIs during a call. |
| **Warm Transfer Calls** | Have the agent contact the transfer recipient before transferring the call. |
The first three and the last are phone actions. **Custom Input** is the one that
creates a custom external action.
Several of these overlap with skills. **[Call Routing](./skills/call-routing)**
and **[End Call](./skills/end-conversation)** cover the same ground with less
setup. Reach for an action when you need a trigger or a configuration the skill
does not offer.
***
## Building a custom external action
| Field | What it does |
| - | - |
| **What is the action name?** | A short name. Required. |
| **How should this action be triggered?** | When the agent should use it, in plain language. Required. |
| **What is the API URL?** | The endpoint to call. Required. |
| **Account Connection** | A connected account, if the endpoint needs one. |
| **Signature Secret** | See the warning below. |
| **Speak on Send** | Whether the agent may say something before the request goes out. |
| **Speak on Receive** | Whether the agent may respond as soon as the result comes back. |
| **Processing Mode** | Muted. This is the only option. |
The trigger question is the important one, and it is not a label. It is what the agent
reads to decide whether this action applies, so write it as a sentence: "If the caller
asks where their order is and has given an order number, look it up."
**Speak on Send** and **Speak on Receive** are toggles, not scripts. You are deciding
whether the agent may speak at those moments, not writing what it says. With both off
the agent goes quiet while the request is in flight, which is what **Muted** means.
Turn **Speak on Send** on for anything slow. Silence on a phone call reads as a
dropped connection, and a caller who hears nothing for three seconds starts saying
"hello?".
***
## The Signature Secret field does nothing
**Signature Secret** is stored and never used. Nothing in Fluents signs outbound
requests, so filling this in does not let your endpoint verify that a request came
from us. Do not treat it as security.
If you need to authenticate incoming requests, put a secret in the URL path or use
an **Account Connection**, and treat the endpoint as publicly reachable.
***
## The input schema
The schema is what the agent has to collect before it may call your endpoint.
**Add Property** takes a **Name**, an optional **Description**, a **Type** and a
**Required field** toggle. Types are **String**, **Number** and **Boolean**. There are
no arrays or nested objects.
The JSON preview beside the form updates as you go, so you can see exactly what your
endpoint will receive.
Descriptions on properties are worth writing. They are how the agent knows what it
is asking for. "The order number the caller gives, digits only" gets you a cleaner
value than a bare `order_number`.
The agent collects the required fields through conversation, calls your endpoint, and
uses the response to carry on.
***
## The list
| Column | What it shows |
| - | - |
| **Name** | The action name, with its type underneath. |
| **Description** | The trigger text you wrote. |
| **Action Trigger** | How it fires, such as Function Call. |
| **Phone Number** | The number involved, for phone actions. |
***
## Actions or webhooks
Both send data to a URL you control. The difference is whether the conversation waits.
An **action** happens during the call and the agent uses the answer. A **webhook**
happens after something occurs and nobody is waiting.
If the agent needs to say something based on the response, you want an action. If you
just need your systems to know, you want a **[webhook](./webhook)**.
***
## Where to go next
* Add the action to an agent: **[Agents](/product/features/agent)**
* Notify your systems instead: **[Webhooks](./webhook)**
* Check whether an action ran on a call: **[Calls](/product/features/call)**
# Agents
Source: https://docs.fluents.ai/product/features/agent
Build the agent that handles your calls. Choose a voice, write the prompt, give it skills, and test it before it talks to anyone.
An **agent** is the thing that talks to people. It has a voice, a prompt telling it
how to behave, and a set of skills letting it do things like transfer a call or book
an appointment.
Go to **Agents** and select **Create Agent** to build one from scratch, or
**Generate Agent** to have one built from a description.
The editor has six tabs. You can save at any point and come back.
| Tab | What you set there |
| - | - |
| **Basic Information** | Voice, greeting, skills, and the prompt. |
| **Data** | Where the agent gets information before a call starts. |
| **Advanced Settings** | Providers, timings, and recording. |
| **Post-Call** | What to extract afterwards and how to judge the call. See **[Post-call](./post-call)**. |
| **Test** | Test cases you can run against the agent. See **[Testing an agent](./agent-testing)**. |
| **More** | The web widget, and the API call equivalent to your setup. |
The **Test** tab only appears if the **Early Access Program** is enabled for your
environment. See **[Experimental features](./experimental-feature)**.
***
## Basic Information
### Voice, language and speed
The top row sets how the agent sounds. Select the voice name to browse and preview
others, set the **Language**, and use **Speed** to make the agent talk faster or
slower. **Reset to recommended** puts the voice back to the default for the language.
Previews play your **Initial Message** in the chosen voice, so you hear the actual
first thing a caller will hear. Text over 50 characters is shortened for the
preview.
### Initial Message
The first thing the agent says. Keep it short and say who is calling.
You can use **variables** here, written in curly braces, so `Hi {first_name}` greets
people by name.
If a variable has no value on a call, the agent reads the placeholder out loud.
Write a greeting that still works when the value is missing, or set a fallback on
the **Data** tab.
### Voicemail Message
What the agent leaves if it reaches an answering machine instead of a person.
### Skills
**Skills** are the things the agent can actually do during a call. Select a skill to
turn it on, then configure it. Most need configuring before they work.
| Skill | What it does |
| - | - |
| **Appointment Scheduling** | Books an appointment on a connected calendar. |
| **Call Routing** | Transfers the call when a phrase is said. |
| **Call Back Later** | Arranges a callback for a better time. |
| **Switch Communication** | Moves the conversation to another channel. |
| **In Call SMS** | Sends a text during the call. |
| **In Call Email** | Sends an email during the call. |
| **End Call** | Ends the call cleanly. |
| **IVR Navigation** | Works through a phone menu to reach a person. |
| **External API** | Calls your own systems mid-conversation. |
| **Call Screen Handling** | Handles a receptionist or screener. |
Searching your own documents is **not** in this list. It is set up on the **Data**
tab under **Knowledge Bases**, not here. See
**[Knowledge Search](./skills/knowledge-search)**.
Each skill has its own settings. **Call Routing** is a good example of the shape they
take:
You set a phrase, and when it is said the call transfers. Two things there are easy
to miss:
* The trigger can listen to the **bot** or the **human**, so you can transfer based
on what the caller says, not only on what the agent says.
* **Transfer type** is either **Direct transfer**, which connects immediately, or
**Warm transfer**, which explains the call to the recipient first.
### Agent Prompt
The prompt is where you tell the agent who it is and how to behave. You can write it
yourself, start from a saved prompt using the dropdown, or have one written for you.
**Generate Prompt** asks what you want the agent to do and writes a prompt tuned for
phone conversations. Describe the job in plain language, including the role, the
tasks, and what a good call looks like.
After generating, a **Revert to Live** option appears. Generating does not save, so
you can try a few versions and go back to the one that was already working.
The saved prompts in the dropdown contain placeholders such as `{COMPANY_NAME}`.
Replace them before you use one, or the agent will read the placeholder aloud.
***
## Data
The **Data** tab is how an agent knows something before the call starts, and what it can
look up while the call is running. Context sources, fallback values, outbound context
memory and knowledge bases all live there.
See **[Data](./data)**.
***
## Advanced Settings
| Setting | What it does | Default |
| - | - | - |
| **Speech to Text** | Which service turns speech into text. AssemblyAI, Deepgram, Deepgram Flux, or Gladia. | Deepgram Flux |
| **Background Sound** | Ambient sound behind the agent. Keyboard, Office, or Office-2. | None |
| **Timezone** | The timezone the agent works in. Used anywhere the agent needs to know the local time, including Call Routing transfer windows. | America/Los\_Angeles |
| **LLM Provider** | OpenAI, Google, Azure OpenAI, or Groq. | OpenAI |
| **Model Name** | Which model from that provider. | GPT-4.1 Mini |
| **Idle Time (seconds)** | How long silence lasts before the agent speaks up. | 7 |
| **Max Idle Check Count** | How many times it checks before giving up. | 3 |
| **Call Duration (seconds)** | Hard limit on call length. | 600 |
| **Extend Call** | Allows a call to run past the limit. | Off |
| **Enable Recording** | Records the audio so you can play it back later. | Off |
**Add Webhook** and **Add Actions** attach a webhook or a library action to this
agent.
If calls feel slow, the provider matters more than the prompt. The **Performance**
tab on any call shows which provider was slow. See **[Calls](./call)**.
***
## Testing before you go live
The right hand panel has **Test Agent**, which offers two ways to try the agent:
* **Start Browser Call** talks to it through your microphone, with no phone number
needed.
* **Start Phone Call** places a real call.
Past test calls are listed beside it, and you can **resume from any point in a
previous conversation** by selecting a line the agent said. That is the fastest way
to re-test one awkward moment without repeating the whole call.
Transfers only work on phone calls, not browser calls.
For repeatable testing rather than one-off calls, see
**[Testing an agent](./agent-testing)**.
***
## Getting the API call
**More** then **Show equivalent code** gives you the exact API request for the agent
as you have configured it, in curl, python, javascript, php, go or java.
This is the quickest way to move from building by hand to building by API. Configure
one agent the way you want it, copy the request, and change what you need.
***
## Where to go next
* Decide what to extract from each call in **[Post-call](./post-call)**.
* Build a repeatable test suite in **[Testing an agent](./agent-testing)**.
* Give the agent a phone number in **[Numbers](./numbers)**.
* Put the agent on your website in **[Web widget](./widget)**.
# Testing an agent
Source: https://docs.fluents.ai/product/features/agent-testing
Build a suite of test conversations and run them against an agent, so you can change a prompt without wondering what you broke.
The **Test** tab lets you keep a set of test conversations and run them against an
agent whenever you change something. It is the difference between hoping a prompt
change helped and knowing it did.
The Test tab only appears if the **Early Access Program** is enabled for your
environment. See **[Experimental features](./experimental-feature)**.
***
## Generating a suite
**Generate suite** reads your agent prompt and writes test cases for you, grouped by
what each one is probing.
The groups are worth understanding, because they are the things that actually go
wrong on live calls:
| Group | What it tests |
| - | - |
| **Flow** | The conversation going as intended, including a clean refusal. |
| **Policy** | The agent holding its line when the caller is wrong about something. |
| **Boundaries** | Difficult callers, such as someone threatening to hang up. |
| **Recovery** | Getting back on track after confusion or interruption. |
| **Actions** | The agent actually doing the thing, not just talking about it. |
**Regenerate tests** replaces the suite. **Add test case** writes one yourself.
***
## Running tests
**Run** executes the whole suite. Each case also has its own run control, so you can
re-run just the one you are working on.
**Setup context** supplies the context values the tests run with, so cases that
depend on a name or an order number behave like a real call.
***
## Building tests from real calls
The best test cases are conversations that already went wrong.
Open a call in **[Calls](./call)** and use **Create test from call** on the Summary
tab. The conversation becomes a case on this tab. You can also reach past calls from
the **Test Agent** panel and resume from any point in one.
When something goes wrong on a live call, turn that call into a test before you fix
the prompt. Then you can prove the fix worked, and you will notice if a later change
breaks it again.
***
## Improve an agent from a call
Testing tells you something broke. **Train your agent** is how you fix it, using a
real conversation as the evidence.
This one is not gated. **Train your agent** works whether or not Experimental
Features are enabled.
You can reach it three ways:
* **Improve agent** on a call's Summary tab in **[Calls](./call)**.
* The **Test Agent** panel, which lists recent calls you can review.
* Ending a browser test call, which drops you straight into it.
The panel puts the call transcript on the left and a feedback box on the right.
Describe what should have happened in plain language. You can also click any agent
message in the transcript to comment on that specific turn, and those comments are
sent along with your overall feedback.
**Get Recommendations** then proposes prompt changes.
### Reviewing the changes
Recommendations never apply silently. They open in a **Prompt changes** window
first.
Green is added text and red is removed. Changes are numbered, and **Previous** and
**Next** step through them. You can reject any single change to keep the original
wording.
**Accept All** applies everything. If you rejected some, the button counts what is
left, such as **Accept 1 Change**.
Accepting only updates the prompt in the editor. Click **Save** on the agent for
the change to take effect on real calls.
Create a test from the call before you accept a recommendation. Then run the suite
afterwards and you will know whether the fix worked.
***
## Where to go next
* Change the prompt and settings you are testing in **[Agents](./agent)**.
* Find the calls worth turning into tests in **[Calls](./call)**.
# Documentation assistant
Source: https://docs.fluents.ai/product/features/assistant
Two ways to find something on this documentation site without reading it end to end.
This documentation site has two ways to find an answer quickly.
These are features of the documentation site you are reading, not of the Fluents
platform.
***
## Search
The search box at the top searches every page. Press Cmd K, or
Ctrl K on Windows, to open it from anywhere.
Search is the better tool when you know roughly what the thing is called.
***
## Ask a question
There is also a chat box that takes a question in plain language and answers from the
documentation.
This is the better tool when you do not know what the thing is called, which is most
of the time. "How do I stop the agent hanging up too early" will find the right page
faster than guessing at a term.
The assistant answers from these pages. Where documentation is wrong or out of date,
the assistant repeats it confidently. If an answer contradicts what you see in the
platform, the platform is right.
***
## When neither helps
Use the **Contact** link in the top navigation, or email
[support@fluents.ai](mailto:support@fluents.ai).
Telling us what you searched for is genuinely useful. A question the docs failed to
answer is a documentation bug, and it gets fixed faster when we know the wording you
tried.
# Calls
Source: https://docs.fluents.ai/product/features/call
Review what your agents did on the phone. Read the Calls table, open a call to see the transcript and insights, filter and export call history, and manage scheduled callbacks.
**Calls** is the record of everything your agents have done on the phone. Use it to
review conversations, find the calls that need attention, and export data for
reporting.
There are two views:
* **History** shows calls that have already happened.
* **Scheduled** shows calls queued to happen later.
On this page:
* [Reading the Calls table](#reading-the-calls-table)
* [Opening a call](#opening-a-call)
* [Filtering call history](#filtering-call-history)
* [Exporting to CSV](#exporting-to-csv)
* [Scheduled calls](#scheduled-calls)
* [Where to go next](#where-to-go-next)
***
## Reading the Calls table
Go to **Calls** and open the **History** tab. Each row is one call.
| Column | What it shows |
| - | - |
| **Start** | When the call began. |
| **Agent Name** | The agent that handled the call. Select it to open the agent. |
| **Numbers** | Who called who. Calls that came through a web widget show **web** on both sides instead of a phone number. |
| **Duration** | How long the call lasted. |
| **Outcome** | How the call ended. |
| **Issues** | Whether anything went wrong on the call. |
| **Result** | Whether the call counted as a success. |
### Outcome
**Outcome** answers "how did this call end".
| Outcome | What happened |
| - | - |
| **Voicemail** | The agent reached an answering machine rather than a person. |
| **Customer Disconnected** | The person hung up. |
| **Bot Disconnected** | The agent ended the call. |
| **In progress** | The call is happening right now. |
| **Error** | Something stopped the call from running. |
Select the information icon next to an outcome to see the specific reason, for
example **Voicemail Detection Hangup**.
### Issues
**Issues** flags calls worth a second look. A call is flagged when it recorded an
error, when an action the agent ran returned an error, or when the agent was slow
to respond.
Response time is graded in two bands. Above **2 seconds** is a warning. Above
**5 seconds** is an error, because delays that long are noticeable to the person on
the call.
A dash means nothing was detected.
Slow responses usually come from a provider rather than from your prompt. If the
same agent keeps getting flagged, try a different Speech to Text or LLM provider
on its **Advanced Settings** tab.
### Result
**Result** is the pass or fail judgement for the call. It stays empty until you set
up **Result Conditions** on the agent's **Post-Call** tab.
| Result | Meaning |
| - | - |
| **Success** | The call met your conditions for a good outcome. |
| **Unsuccessful** | The call met your conditions for a bad outcome. |
| **Neutral** | Neither set of conditions matched. |
If a call matches both sets of conditions, it counts as **Unsuccessful**.
***
## Opening a call
Select any row to open **Call Overview**.
The left side shows the **transcript**, with each turn timestamped and labelled as
the caller or the agent. If recording was enabled for the agent you can play the
audio here. You can also download the transcript.
The right side has four tabs:
**Summary** gives you the call's duration, its outcome, and any **insights** your
agent extracted. Two actions live here:
* **Create test from call** turns this conversation into a test case on the agent's
**Test** tab.
* **Improve agent** opens the agent's **Train your agent** panel with this call's
transcript loaded, so you can turn what went wrong into prompt changes. See
[Improve an agent from a call](/product/features/agent-testing#improve-an-agent-from-a-call).
**Action History** lists the actions the agent ran during the call, such as a
transfer or a lookup against your own system.
**Performance** shows how quickly the agent responded, broken down by the speech,
language, and voice providers it used, along with any configuration problems found
on the call. It also shows the **context** the call started with. Only the values you passed in
appear here, not the ones Fluents adds internally.
**Config** shows the settings this particular call ran with, such as the provider
that carried it and whether Do Not Call detection was run.
**Create test from call** is the fastest way to build a test suite. Rather than
inventing test cases, find the calls that went wrong and turn each one into a
test.
***
## Filtering call history
Select **Filters** to open the filter panel. Filters combine, so you can narrow by
several at once.
| Filter | Use it to |
| - | - |
| **Period** | Restrict to a date and time range. |
| **Agents** | Show calls handled by specific agents. |
| **Statuses** | Filter by status. |
| **Call ID** | Jump straight to one call. |
| **Contact Number** | Show every call to or from one phone number. |
| **Duration (seconds)** | Focus on shorter or longer calls. |
| **Successful Actions** | Show calls where specific actions completed. |
| **Result** | Filter to Success, Unsuccessful, or Neutral. |
| **Skill Type** | Show calls where a specific skill ran. |
| **Transcript Keyword** | Search what was said. |
| **Campaign** | Show calls generated by a specific campaign. |
| **Call Insights** | Filter on what your agent extracted from the call. |
| **Call Context** | Filter on a value you passed into the call. |
### Status values
**Not started**, **In progress**, **Voicemail**, **Is not voicemail**, **Error**,
and **Ended**.
**Is not voicemail** excludes machine-answered calls in one step, which is usually
what you want when reviewing outbound results.
### Filtering by Call Insights
Select **Add Row**, choose an insight, choose an operator, then enter the value to
match. Each extra row narrows the list further, so a call has to match all of them.
Use this for questions like "show me every call where the caller asked for a refund".
### Filtering by Call Context
Select **Add Row** and enter a **Key** and **Value**. This searches the context you
passed into the call, such as a customer ID or an order number, so it is the
fastest way to find every call tied to one record in your own system.
The **Skill Type** filter does not match the **Call Screen Handling** skill.
Calls where that skill ran will not appear when you filter by it.
***
## Exporting to CSV
Apply your filters first, then select **Export CSV**. The export always reflects the
filters currently applied, so narrow the list before exporting rather than
exporting everything and cutting it down afterwards.
You choose which columns to include:
**ID**, **Agent**, **Agent Name**, **Call Context**, **Transcript**, **Start Time**,
**End Time**, **Duration (s)**, **From Number**, **To Number**, **Status**,
**Result**, **Insights**, **Call SID**, **Account SID**, **Stream SID**,
**Encoding**, **Provider**.
You can drag the headers to change the order they appear in.
Choose how you want the file. **Download CSV** is capped at **1,000 calls**.
**Send by email** handles far more, up to 100,000 calls, so use it for anything
larger.
Turn on **Expand Insights** to give each insight its own column rather than packing
them all into one field. Do that if the file is going into a spreadsheet or a
reporting tool.
In a HIPAA-enabled environment, **Transcript** and **Insights** are not available
as export columns.
### Useful combinations
* **Real conversations only.** Status **Is not voicemail**, plus duration greater
than 30 seconds. This removes unanswered and machine-answered calls.
* **Calls to review.** Filter **Result** to **Unsuccessful**, or scan the **Issues**
column.
* **One customer's history.** Use **Contact Number**, or **Call Context** with your
own record ID.
* **Campaign review.** Use **Campaign**, plus **Call Insights** for the outcome you
care about.
Include **Call SID** and **Start Time** in any recurring export. Those two let you
match Fluents records against your phone provider's own records later.
***
## Scheduled calls
Open the **Scheduled** tab to see calls that have not happened yet. They come from
two places: callbacks an agent agreed to during a conversation, and calls queued by
a campaign.
| Column | What it shows |
| - | - |
| **Created At** | When the call was queued. |
| **Campaign** | The campaign it belongs to, if any. |
| **Agent** | The agent that will handle it. |
| **From** and **To** | The numbers that will be used. |
| **Scheduled Time** | When the call is planned. |
| **Status** | Where the call has got to. |
| **Activity** | Recent events, such as the last attempt. |
Campaign calls are labelled by their place in the sequence, starting with **Initial
Call**, then **Follow-up Call #1** and so on. Callbacks an agent arranged are
labelled **Callback**.
### Status values
| Status | Meaning |
| - | - |
| **Scheduled** | Queued and waiting for its time. |
| **Pending** | Held back by a limit, most often the number of calls your plan lets you run at once. |
| **In Progress** | Running now. |
| **Exited** | The contact left the campaign because they met an exit criterion. |
| **Canceled** | Canceled before it ran. |
| **Canceled (Contact Reached)** | Canceled automatically because you reached the contact another way. They answered an earlier call, or they called you. |
| **Errored** | The call could not be placed. |
### Filtering
The Scheduled tab has its own filters for **Agents**, **Campaigns**, **Statuses**,
whether the call came from a callback or a campaign, and a date range. There is no
CSV export on this tab.
Callbacks only appear here if the agent has the **Call Back Later** skill enabled.
***
## Where to go next
* Set up what your agent extracts and how calls are judged in
**[Agents, Post-Call](../concepts/agent/post-call)**.
* Change providers, recording, and call duration in
**[Agents, Advanced Settings](../concepts/agent/advanced)**.
* See how campaigns generate the calls that land here in
**[Campaigns](./campaigns)**.
# Campaign Schedules
Source: https://docs.fluents.ai/product/features/campaign-schedules
Set the days, hours and timezone your campaigns are allowed to contact people. A schedule is required before you can create a campaign.
A **campaign schedule** decides when a campaign is allowed to contact someone. It
sets the days of the week, the hours within those days, and the timezone those
hours are measured in.
You need at least one campaign schedule before you can create a campaign. The
campaign dialog will not let you continue without one.
Schedules are reusable. Most teams keep a small number, such as one for business
hours and one for evenings, and point every campaign at the right one.
***
## Creating a schedule
Go to **Campaigns** in the sidebar, then **Schedules**, and select **New Campaign
Schedule**. You can also create one without leaving the campaign dialog, using
**Create campaign schedule**.
Give the schedule a name by selecting the title, and a description if it helps your
team tell two schedules apart. A summary of the days you have picked appears under
the name as you edit.
### Outreach Schedule
Select the days you want outreach to go out on. Monday to Friday are selected by
default.
Then set **Allowed contact times**, the window within each of those days. The
default is **9:00am to 7:00pm**.
### Timezone
**Primary** sets the timezone the contact times are measured in. The default is
**Pacific Time**.
The timezone applies to the whole schedule, not to each contact. A 9:00am start
in Pacific Time reaches someone on the east coast at noon their time. If you are
calling across timezones, use a window that is reasonable at both ends.
Select **Save & Exit** when you are done. If you created the schedule from inside
the campaign dialog you are returned there with the new schedule selected.
***
## Reading the schedules list
| Column | What it shows |
| - | - |
| **Name** | The schedule's name. |
| **Description** | Your note about what it is for. |
| **Days** | The days outreach is allowed. |
| **Time Range** | The allowed contact times. |
| **Timezone** | The timezone those times are measured in. |
***
## Where to go next
* Use a schedule when you set up outreach in **[Campaigns](./campaigns)**.
* Control how often each of your numbers is used in **[Numbers](./numbers)**.
# Campaigns
Source: https://docs.fluents.ai/product/features/campaigns
Reach a list of contacts automatically by phone, email or SMS. Set up a campaign, build the outreach flow, import contacts, and start it.
A **campaign** reaches a list of contacts for you, one contact at a time, following
a sequence you define. Each contact enters the campaign, moves through your
outreach steps, and leaves when they respond or when the campaign runs out of steps.
Outreach is not only phone calls. A step can be a **phone call**, an **email**, or
an **SMS**, so a campaign can call someone and follow up by text a day later.
## Before you start
Two things must exist first. Set both up and the rest takes a few minutes.
Sets the days, hours and timezone the campaign may contact people. See
**[Campaign schedules](./campaign-schedules)**. The dialog will not let you
continue without one.
Calls have to come from somewhere. See **[Numbers](./numbers)**. Without one you
can build the whole campaign and still not be able to create it.
***
## 1. Name it and pick a schedule
Go to **Campaigns** and select **New Campaign**.
Enter a **Campaign name**. Then choose a **Campaign schedule**. The dialog shows the
schedule's days, hours and timezone so you can check it before continuing. If you
have none, **Create campaign schedule** takes you to the editor and brings you back.
Select **Next**.
## 2. Build the outreach flow
The flow starts from **When a contact is added**. Everything below happens to each
contact in order.
Each step has a type: **Phone call**, **Email**, or **SMS**. A phone call step needs
an **Agent**.
**Add next outreach** adds a follow up, with a delay between the two. The delay
defaults to **1 day after phone call**, and you can change both the number and the
unit.
Follow up steps default their agent to **Same as initial call**, and offer two
options the first step does not have:
* **Override initial message**, so a second call can open differently from the first
* **Override voicemail message**
A second call that opens with "Hi, I tried you yesterday" lands far better than
one that repeats the original greeting. That is what Override initial message is
for.
Select **Next**.
## 3. Choose who it comes from
**Calls will come from** picks the caller ID your contacts see. You can select
**individual numbers**, or a **tag**, which uses every number carrying that tag and
spreads the traffic across them.
**Exit Criteria** shows when a contact is automatically removed. These are fixed and
cannot be edited:
* The contact answers a call from this campaign
* The contact asks to stop receiving communication on any channel
* The contact's number is unreachable
Select **Create Campaign**. The campaign is created as a **Draft** and does not
contact anyone yet.
***
## 4. Add contacts
On the **Contacts** tab, choose **Upload a CSV** or **Set up CRM integration**.
For a CSV, drop the file in and confirm **Data has headers**. **Skip contacts with
duplicate phone numbers** is on by default, so re-uploading a list will not create
duplicates.
Then **drag** the column holding the phone number onto **To Number**. That is the
only required mapping. Every other column comes along as context your agent can use,
so a `first_name` column lets the agent greet people by name.
Select **Import**. Any row that cannot be imported is listed with its row number and
the reason, and the rest still import.
A contact can be a phone number, a **SIP URI**, or a **WhatsApp address**. Numbers
are validated on import, so reserved test ranges such as `555` are rejected.
***
## 5. Start it
Use **Start** to begin, or **Schedule Start** to begin at a future time. Until then
the campaign stays a **Draft**.
The campaign page has five tabs:
| Tab | What it is for |
| - | - |
| **Overview** | Total contacts, how many are Scheduled, Exited and Errored, the start date, and **Step metrics** broken down by outreach step. |
| **Communication** | The outreach flow you built. |
| **Contacts** | Who is in the campaign and where each came from. |
| **Activity** | What the campaign has been doing. |
| **Settings** | The campaign's own configuration. |
Campaign statistics may be delayed by up to **4 hours**. If a number looks wrong
straight after a run, check again later before investigating.
***
## Reading the campaigns list
**Manage** lists your campaigns and **Monitor** shows activity. The **In Use** and
**Archived** filters switch between active and retired campaigns.
| Column | What it shows |
| - | - |
| **Created At** | When it was created. |
| **Campaign Name** | Its name. |
| **Status** | Whether it is running. |
| **# Scheduled** | Contacts with outreach queued. |
| **# Exited** | Contacts who have left. |
| **# Errored** | Contacts whose outreach could not be delivered. |
***
## Keeping deliverability healthy
Carriers flag numbers that call too much. Two habits protect you:
* Keep a single number under roughly **100 calls per day**. Add numbers and use a
tag to spread traffic rather than pushing one number harder.
* Set **call pacing** on your numbers so the platform spaces calls out for you. See
**[Numbers](./numbers)**.
Before running production volume, register your business with us so your numbers are
set up correctly with our telephony partners.
***
## Where to go next
* Set the days and hours outreach is allowed in **[Campaign schedules](./campaign-schedules)**.
* Buy, tag and pace numbers in **[Numbers](./numbers)**.
* Review what happened on campaign calls in **[Calls](./call)**.
# Dashboard
Source: https://docs.fluents.ai/product/features/dashboard
The first screen after signing in. Headline numbers on call health, and a short list of what needs your attention.
The **Dashboard** is the overview. It answers "is anything wrong" in a glance, and
hands off to **[Calls](./call)** or **[Reports](./reports)** when the answer is yes.
Everything is scoped to the current environment and to the **date range** shown at the
top right, which displays both the period name and the actual dates it covers.
***
## The tiles
Each tile shows a figure, a comparison against the previous period of the same length,
and a small trend line.
| Tile | What it counts |
| - | - |
| **Calls** | Calls in the period. |
| **Connect rate** | The share that reached someone. |
| **Escalations** | The share that had to be handed on. |
| **Voicemails reached** | Calls that reached voicemail rather than a person. |
Two more sit underneath.
**Avg. call duration** is the mean length of a call.
**Minutes used** is your consumption against your plan.
**Minutes used is monthly.** It ignores the date range, unlike everything beside it.
Narrowing the range to a single day will not narrow this figure.
The comparison against the prior period is more useful than the figure. A connect
rate of 40% means nothing on its own. A connect rate that fell 15 points last week
means something.
***
## Agent performance
Lists your agents with a breakdown of how their calls went, in green, amber and red,
plus a total. The agent name links through to the agent.
Use it to spot the one agent dragging an otherwise fine number down.
***
## Calls flagged for review
Calls the system thinks are worth a human look, shown as a count and a share of recent
activity. When there is nothing to see, it says so.
***
## A caveat on the date range
The tiles respect the date range. **Agent performance** and **Calls flagged for
review** appear not to. It is possible to see **Calls** reading 0 for a period while
Agent performance reports calls in the same view, because those panels are counting
recent activity rather than your selected window.
If the two disagree, trust the tiles for anything date-scoped, and treat the lower
panels as a view of recent activity.
***
## When you need more
The Dashboard is fixed. You cannot add a tile or change what it measures.
When you need a specific question answered, or a chart over one of your own insights,
build it in **[Reports](./reports)**.
***
## Where to go next
* Look at the individual calls: **[Calls](./call)**
* Build your own charts: **[Reports](./reports)**
* Extract the things worth measuring: **[Post-call](./post-call)**
# Data
Source: https://docs.fluents.ai/product/features/data
What an agent knows before the call connects, and what it can look up while the call is running.
The **Data** tab decides what an agent knows. There are four parts, and they answer
different questions.
| Part | Answers |
| - | - |
| **Context Sources** | Fetch facts from your systems before the call connects. |
| **Fallback Values** | What to use when a fact is missing. |
| **Outbound Context Memory** | Carry what a campaign knew into a call back. |
| **Knowledge Bases** | Documents the agent can search mid-call. |
***
## Context Sources
A context source fetches data before the call and maps the response onto context
variables the prompt and the opening line can use. An agent can have up to five.
Click **Add Source**.
| Field | What to set |
| - | - |
| **Type** | **Custom** for your own endpoint, or **Integration** to use a connected integration. |
| **Method** | The HTTP method. |
| **URL** | The endpoint to call. |
| **Required** | On means the call does not go ahead without a response. Leave it off unless the call is pointless without the data. |
Open **Request details** for **Headers** and **Query parameters**.
### The phone numbers are sent for you
Fluents adds the call's phone numbers to every source request, with no configuration:
| Parameter | What it holds |
| - | - |
| `from_phone` | The number the call came from. On an inbound call, your caller. |
| `to_phone` | The number that was dialed. On an inbound call, yours. |
| `phone_number` | The other party's number for the call. |
Adding your own query parameters **replaces the default phone fields**. If you need
custom parameters, add `from_phone` back yourself.
### Mapping the response
**Test request** runs the call and shows you a real response. **Auto-map all fields**
creates the mappings for you, or you can build them by hand under **Variable
Mappings**.
Return a `200` with an empty object rather than a `404` when you do not recognise the
caller. Unknown callers are normal and you want the call to continue.
***
## Fallback Values
Used when a source does not return a value. Without them, a missing fact leaves a hole
in your greeting.
Set one for every variable that appears in the **Initial Message**. For a name, a
neutral value reads better than a blank.
| Variable | Fallback |
| - | - |
| `first_name` | `there` |
Fluents supplies some context on its own, including today's date and tomorrow's date,
so you do not need to provide those.
***
## Outbound Context Memory
Under **Configuration**. This is how an agent recognises someone your campaign called
earlier when they ring the number back.
A campaign already carries per contact context such as `first_name`, `last_name` and
`email`, with `to_number` as the contact's number. Tick this box and that context
becomes available on the inbound call too.
Inbound calls combine context with the last outbound call between the same numbers,
filling only missing details.
There is nothing to build. No endpoint, no mapping, nothing to keep in sync.
Matching is on the numbers. If the contact rings back from a different phone, from a
switchboard, or with the number withheld, there is nothing to match and the call
arrives cold. Write the greeting so it survives that, and set fallback values.
It fills **missing** details only, so anything the call already knows wins. And it needs
a previous outbound call between those two numbers, so it does nothing for a caller you
have never dialed.
### Which one do I want
Use **Outbound Context Memory** for people your campaigns already called. Use a
**Context Source** for anything that lives outside Fluents, such as an order status or
a CRM record, and for callers who were never in a campaign. They work together.
***
## Knowledge Bases
At the bottom of the tab. These are the documents the agent can search during a call,
rather than facts fetched before it. Attach them here, then see
**[Knowledge search](./skills/knowledge-search)** for how the agent uses them.
***
## Where to go next
* **[Agents](./agent)** for the rest of the agent settings.
* **[Campaigns](./campaigns)** for the contact context that feeds Outbound Context Memory.
* **[Post-call](./post-call)** for what comes out of a call rather than what goes in.
# DNC List
Source: https://docs.fluents.ai/product/features/dnc-list
The list of numbers your agents must not call, including the ones the platform adds for you when someone asks to be left alone.
The **DNC List** is the set of phone numbers your agents will not call. Numbers get on
it two ways. You add them, or Fluents adds them when a caller asks to stop being
contacted.
***
## The list
| Column | What it shows |
| - | - |
| **Date Added** | When the number was added. |
| **Phone Number** | The number. |
| **Created By** | Who added it, you or Fluents. |
| **Reason** | Why, if a reason was given. |
The **Created By** filter defaults to **User**, so the list you see on arrival
contains only the numbers **you** added. Numbers the platform added automatically
are hidden until you switch the filter to **Fluents** or **All**.
If you are checking whether a specific number is suppressed, switch to **All**
first. The default view will tell you it is not there when it is.
***
## Adding a number
Click **New**, enter the **Phone Number**, and optionally a **Reason**.
The reason is for you, not the system. Six months from now, "asked to be removed on
the June campaign" is the difference between confidence and guesswork.
Numbers are added one at a time. There is no bulk import. **Export CSV** takes the
list out, but nothing brings a list in.
***
## Numbers Fluents adds for you
When a caller asks not to be contacted again, the platform records it. Those entries
show **Fluents** as the creator.
This is why the filter default matters. The automatic entries are the ones you did not
know about, and they are the ones hidden by default.
***
## Where to go next
* See whether do not call was detected on a call: **[Calls](./call)**
* The numbers your agents call from: **[Numbers](./numbers)**
* Reaching a list of contacts: **[Campaigns](./campaigns)**
# Early Access
Source: https://docs.fluents.ai/product/features/experimental-feature
Turn on features that are still being built, for one environment at a time.
**Early Access** gives an environment features that are not finished yet. It is a
single switch per environment. There is no picking individual features.
***
## Turning it on
Open **Settings**, go to **Environments**, and edit the environment. The toggle is
**Early Access Program**.
Joining means agreeing that Fluents may contact you for product feedback or usability
sessions. That is stated on the toggle itself, and it is the actual trade. You get
the features early, they get to ask you how it went.
The switch is per environment, so you can run it on a test environment and leave
production alone. That is what most people should do.
***
## What it unlocks
Once it is on, an **Early Access** section appears in the sidebar with:
* **Messages**
* **BYOC**
It also enables the **Test** tab on agents, where you build and run test suites. See
**[Testing an agent](./agent-testing)**.
***
## What to expect
These features are unfinished by definition. They can change without warning, move to
beta, or be removed. Labels move, behaviour shifts, and documentation lags.
Do not build a production process on an early access feature without a plan for it
changing under you.
***
## Where to go next
* The one most people turn this on for: **[Testing an agent](./agent-testing)**
* Environment caps and keys: **[Settings](./account/settings)**
# Knowledge Bases
Source: https://docs.fluents.ai/product/features/knowledge-base
Store documents your agents can search during a call, so they answer from your content instead of improvising.
A **knowledge base** is a collection of documents your agents can search while they
are talking. Without one, an agent answers from its prompt, and when the prompt does
not cover something it improvises. With one, it looks the answer up.
***
## Create one
Go to **Knowledge** and click **Create Knowledge Base**. All it asks for is a name.
Creation is not instant. You will see a message saying the knowledge base is
scheduled for creation and to check back in a few minutes, and it will not appear in
the list straight away. Nothing has gone wrong. Refresh after a minute or two.
Name it after the questions it answers rather than the file it came from. "Returns and
refunds" is easier to reason about later than "policy-doc-v3".
***
## Add documents
Open the knowledge base and drag files onto the drop zone, or click it to browse.
Supported file types are **PDF, TXT, RTF, DOC, DOCX, PPT, PPTX and HTML**.
Spreadsheets are not supported. There is no CSV, XLS or XLSX. If your content lives
in a spreadsheet, export it to one of the formats above first.
Uploaded files are listed with an ID and a name.
***
## Let an agent use it
Creating a knowledge base does not connect it to anything. Open the agent, go to the
**Data** tab, find **Knowledge Bases**, and click **Add Knowledge Base**.
This is not under **Choose Skills**, which is where most agent abilities live. It is
on the **Data** tab.
Each attachment asks **When should this be used?**, and that answer is what decides
when the agent searches. It is an instruction, not a label. Write it as the list of things a
customer might ask about, in their words. A vague description means the agent never
searches and answers from the prompt instead.
The **[Knowledge Search](./skills/knowledge-search)** page covers this in full.
***
## What to put in
Documents written for people to read work better than documents written for filing.
* **Prefer answers over policy.** A page that says what happens is more useful than
one that says what the rules are.
* **Split by topic.** Several focused knowledge bases with clear descriptions beat one
large one, because the description is what routes the search.
* **Leave out anything you would not want read aloud.** The agent is speaking, not
linking.
***
## Where to go next
* Connect it to an agent: **[Knowledge Search](./skills/knowledge-search)**
* Check the agent actually searches when it should: **[Testing an agent](/product/features/agent-testing)**
* Put stable instructions in the prompt instead: **[Prompts](./prompts)**
# Numbers
Source: https://docs.fluents.ai/product/features/numbers
Buy or connect the phone numbers your agents call from and answer on, and control how hard each one is worked.
**Numbers** is where the phone numbers live. An agent needs one to place outbound
calls, and an inbound agent needs one pointed at it before anybody can reach it.
***
## What the top of the page tells you
Three figures sit above the table, and they answer different questions.
| Figure | What it means |
| - | - |
| **Total numbers** | How many numbers your plan allows in total. |
| **Allocated across environments** | How many of those have been handed out to environments. |
| **Active in ``** | Numbers in use in the named environment against its cap. |
**Buy more** takes you to **Billing**, because the number allowance comes with your
plan rather than being bought a number at a time.
**Edit allocation** opens the environment's settings, where **Max Purchasable
Numbers** sets this environment's cap. The same dialog holds **Max Concurrent Calls**,
which is the other limit people run into.
Numbers belong to an environment. A number bought in one environment is not
available in another, which is usually what you want, and occasionally a surprise.
***
## Adding a number
**Buy new** gets you a fresh number from a provider. Choose the **Provider**, then
open **Number** and pick from the available list. You can search it, tick several, or
use **Select all** to take a batch at once.
**Link existing** connects a number you already own elsewhere. You supply the provider
and the phone number rather than choosing from a list.
**Link existing** needs a connected telephony account. Connect it under
**Integrations** first, then pick it as the **Account Connection** when you link the
number. See **[Providers and connections](/product/features/providers)**.
Either way, two optional fields are worth filling in as you go.
**Inbound Agent** is the agent that answers calls to this number. Leave it empty and
the number can still place outbound calls, but nothing happens when somebody rings it.
**Tags** are how campaigns pick a caller ID. A campaign can select numbers by tag
rather than one at a time, so tagging by region or by purpose as you buy saves work
later.
***
## The table
| Column | What it shows |
| - | - |
| **Number** | The number, with a copy button. |
| **Agent** | The inbound agent answering it, or a dash. |
| **Telephony** | The provider carrying it. |
| **Account Connection** | The connected provider account, if you linked one. |
| **Tags** | Tags on the number. |
| **Deletion Date** | When a number is due to be released. Hidden in the In Use view. |
Filter by agent or by tags, search by digits, and switch the status filter between
**In Use**, **Archived** and **All**.
***
## Call pacing
This is the setting that most people need and few people find.
Tick **Limit call frequency** and you get two controls, both applied **per number**.
* **Wait N minutes between calls.** A cooldown after each call.
* **No more than N calls every N hours.** A ceiling over a window.
Carriers flag numbers that dial hard and fast, and a flagged number starts showing up
as spam on people's handsets. Pacing is how you avoid that. Click **Save** to apply.
Pacing is per number, so the way to get more volume without dialing any single
number harder is to buy more numbers and spread the traffic. Roughly 100 calls per
day per number is a reasonable ceiling.
***
## Removing a number
Two different actions, and the difference matters.
**Archive** unassigns the number from its agent. Calls to it stop reaching that agent,
but you keep the number.
**Schedule delete** gives the number up for good.
Archive if you are unsure. Deleting releases the number, and you will probably not
get the same one back.
***
## Where to go next
* Point a number at an agent: **[Agents](/product/features/agent)**
* Use tags to choose a caller ID: **[Campaigns](/product/features/campaigns)**
* Environment caps and keys: **[Settings](/product/features/account/settings)**
* Stop calling people who asked you not to: **[DNC List](/product/features/dnc-list)**
# Post-call
Source: https://docs.fluents.ai/product/features/post-call
Decide what to pull out of every call, judge whether the call went well, and send a follow up email or SMS afterwards.
Everything on an agent's **Post-Call** tab happens after the conversation ends. It
turns a recording into something you can search, count and act on.
There are four parts:
1. **Call Insights** pull specific facts out of the conversation.
2. **Result Conditions** decide whether the call counted as a success.
3. **Post-Call Messaging** sends a follow up email or SMS.
4. **Sync Post-Call Activity to CRM** records it in your CRM.
***
## Call Insights
An **insight** is one thing you want to know about every call. The caller's name.
Whether they agreed to a follow up. Which product they asked about.
Once configured, insights show on each call in **[Calls](./call)**, can be filtered
on, and can be included in a CSV export.
### Creating an insight
Select **Add Call Insight**, then either **Create new insight** or **Add existing
insights** to reuse one already defined in this environment.
A new insight needs four things:
| Field | What it is |
| - | - |
| **Description** | What you are trying to learn, in plain language. |
| **ID** | The short name you use to refer to it elsewhere. It fills in from the description. |
| **Type** | Yes / No, Number, Selector, or Text. |
| **How to determine this insight** | Instructions for reading the value out of the call. |
**Selector** adds a **Choices** list, so the answer has to be one of the options you
allow. That is what makes an insight countable later, rather than free text you have
to read.
**Test Insight** runs it before you save.
Pick **Selector** over **Text** whenever you can. "Order issue, Product question,
Something else" can be charted. A sentence cannot.
### Generating insights
**Generate Insights** reads your agent prompt and proposes a set for you.
It is a good starting point, but check the **ID** on each one. Generated insights get
long automatic identifiers, and the ID is what you type when referencing an insight
in a filter or a message template. Rename them to something short before you rely on
them.
***
## Result Conditions
**Result Conditions** turn a call into a pass or a fail. The result appears in the
**Result** column in Calls, drives the **Agent performance** panel on the Dashboard,
and can be filtered and exported.
You build two rule sets, one for **Successful outcome** and one for **Unsuccessful
outcome**. Each condition is based on either a **Call** property, such as whether
voicemail was detected, or a **Call Insight** value.
How the logic works:
* Conditions inside one set must **all** be true.
* **Or if** starts another set. Any set matching is enough.
* If a call matches both the successful and unsuccessful rules, it counts as
**Unsuccessful**.
With no conditions configured, every call shows a blank Result. This is the most
common reason the Result column looks empty.
***
## Post-Call Messaging
**Add Message** creates a rule that sends an email or an SMS after the call. You can
add several, each with its own conditions, so a call that went one way gets a
different follow up from one that went another.
***
## Sync Post-Call Activity to CRM
Records call insights and messaging activity against the contact in your CRM. Pick
the connection you want to write to. Connections are set up in
**[Integrations](./providers)**.
***
## Where to go next
* See insights and results on real calls in **[Calls](./call)**.
* Configure the agent that produces them in **[Agents](./agent)**.
* Connect a CRM in **[Integrations](./providers)**.
# Prompts
Source: https://docs.fluents.ai/product/features/prompts
Keep reusable prompts and building blocks in one place, so agents start from something known rather than a blank box.
**Prompts** is a library. It holds full agent prompts you can start an agent from, and
smaller **building blocks** you can drop into a prompt you are writing.
The point is not to store text. It is that a prompt you got right once should not have
to be rewritten from memory the next time.
***
## Two types
| Type | What it is |
| - | - |
| **Prompt** | A complete agent prompt. Selectable when you set up an agent. |
| **Building Block** | A fragment you insert into a prompt while writing it. |
Fluents ships examples of both. **Sales**, **Debt Relief** and **Customer Support**
are prompts. **Disfluencies**, **Book Appointment** and **Appointment Retrieval** are
building blocks.
Filter the list by **Type**, by **Created By** to separate the built-in ones from your
own, or search the content directly.
***
## Writing one
**Create Prompt Template** opens the editor.
Give it a **Name**, choose the **Type**, and write the **Content**.
The **Building Blocks** panel on the left holds the blocks available to you, grouped
by what they are for, such as **Objectives**, **Guidelines**, **Contexts** and
**Examples**. You will only see groups you actually have blocks for. The arrow beside
each one drops it into your content, so you assemble rather than retype.
***
## What makes a prompt work
The editor carries this guidance, and it is worth repeating because it is the
difference between an agent that behaves and one that improvises.
* **Keep instructions simple.** Simple instructions are more reliable than complex
ones. This is the one people ignore.
* **Spell out unusual words phonetically.** Product names and proper nouns get
mangled otherwise, because the agent is reading them aloud.
* **Split large prompts into sections.** A wall of text is harder for the agent to
follow than the same content under headings.
* **Give examples of what you want.** Showing beats describing.
***
## Using a prompt on an agent
Open the agent and find **Agent Prompt** on the **Basic Information** tab. The
dropdown above the text box lists the prompts in your library. Pick one and it fills
the box, after which you can edit it freely for that agent.
Only entries of type **Prompt** appear in that dropdown. Building blocks do not,
because they are meant to be composed into a prompt here rather than used as one.
The dropdown lists prompts by their **content**, not their name. A library of well
named prompts still shows up as a list of first lines, so make the opening sentence
of each prompt distinctive enough to recognise.
Choosing a prompt copies it. Editing the agent's prompt afterwards does not change the
library, and editing the library entry does not change agents already using it.
***
## Where to go next
* Put the prompt to work: **[Agents](/product/features/agent)**
* Have the agent propose prompt changes from a real call: **[Testing an agent](/product/features/agent-testing)**
* Reference stored content instead of writing it into the prompt: **[Knowledge Bases](/product/features/knowledge-base)**
# Providers and connections
Source: https://docs.fluents.ai/product/features/providers
Connect the services your agents use, and bring your own API key for the telephony, transcription, LLM and voice providers Fluents runs on.
Everything lives under **Integrations** in the sidebar, split into two tabs.
| Tab | What it holds |
| - | - |
| **External** | Services you connect, such as your CRM, calendar, email or SMS tool. Each one starts as **Not connected**. |
| **Built-in** | The providers Fluents runs on for telephony, transcription, LLM and voice. They work out of the box with Fluents-managed accounts. |
***
## External connections
Each service you connect is an **account connection**, made once and then reused.
The tab groups them as **CRM**, **Calendar**, **Email**, **SMS** and **Misc**. Click
**Connect** on a card to add one.
Once a connection exists, it becomes selectable wherever it is relevant. The
**Account Connection** field you see on numbers, actions and webhooks is asking which
of your connections to use.
**Calendars** let the
**[Appointment Scheduling](/product/features/skills/appointment-scheduling)** skill
read real availability and book into it.
**Email accounts** let the
**[In Call Email](/product/features/skills/in-call-email)** skill send from your
domain rather than a generic sender.
**CRMs** let post-call results sync into the system your team already looks at. See
**[Post-call](/product/features/post-call)**.
**Telephony accounts** let you link numbers you already own instead of buying new
ones. See **[Numbers](/product/features/numbers)**.
Need a service that is not listed? Click **Request an integration** at the top of the
page and describe how you would use it.
***
## Use your own provider API key
Every provider on the **Built-in** tab shows **Default**, which means it runs on a
Fluents-managed account. To use your own account instead:
1. Open **Integrations** and go to the **Built-in** tab.
2. Click **Use my account** on the provider.
3. Paste your API key.
4. Click **Add**.
| Category | Providers |
| - | - |
| **Telephony** | Telnyx, Twilio |
| **Transcription** | AssemblyAI, Deepgram, Gladia |
| **LLM** | Azure LLM, DeepSeek, Google, OpenAI, Together AI |
| **Voice** | Azure Speech, Cartesia, ElevenLabs, Rime |
| **Auth** | API Key Auth |
Most providers only ask for an API key. Some ask for more. **Azure LLM** also needs
its **URL**, and **Twilio** asks for the **Account SID** and **Auth Token**.
***
## A note on scope
Connections belong to an **environment**, like everything else. A calendar connected
in one environment is not available in another, so an agent that books fine in testing
will not book in production until the connection exists there too.
***
## Where to go next
* The integrations themselves are documented in the **Integrations** section.
* **[Settings](/product/features/account/settings)** for environments.
* **[Numbers](/product/features/numbers)** for linking numbers you already own.
* **[Voices](/product/features/voice)** for importing a voice from your provider account.
# Reports
Source: https://docs.fluents.ai/product/features/reports
Build your own charts over call data and insights, then run them over a date range.
Reports is in **beta**. Expect it to change.
**Reports** lets you answer questions the Dashboard does not. You assemble a **view**
out of chart blocks, then run it over a date range to produce a **report**.
The split matters. A view is the question. A report is one answer, from one date
range, frozen at the moment you ran it.
***
## Build a view
Go to **Reports**, stay on the **Views** tab, and click **Create View**. Name it,
optionally describe it, then click **Add block**.
Each block is one chart.
| Setting | Options |
| - | - |
| **Name** | Fills itself in from the metric. Editable. |
| **Filters** | Which calls count. A live counter shows how many match as you add them. |
| **Metric** | What to measure. Either a **call field** or one of your **insights**. |
| **Aggregation** | How values are combined. See below. |
| **Chart** | Bar, Line, Donut or Number. Bar is the default. |
| **Group by** | All, Hour, Date or Week. Date is the default. |
The preview updates as you go.
**Aggregation** behaves differently depending on the metric. For a yes/no or
categorical metric it is fixed and simply tells you what it is doing, such as counting
or taking the top five values. For a **numeric** metric you choose: **Sum**,
**Average**, **Min** or **Max**, defaulting to Average.
Add as many blocks as you want. A view holds several charts, and blocks can be
reordered, duplicated or removed.
The preview uses **recent data**, not your chosen date range. It is there to show
you the chart is wired up correctly. The numbers that count come from the generated
report.
***
## Metrics
Metrics come from two places, and the list tags each one.
**Call fields** are properties of the call itself. Direction, status, stage, result,
duration, end reason, voicemail detection, do not call detected, recording available,
and the latency figures for the speech, language and voice providers.
**Insights** are the things your agents extract. Anything you set up under
**[Post-call](./post-call)** becomes available here.
Insights are what make this worth using. Charting call fields tells you how the
system behaved. Charting insights tells you what customers said, which is the
question you actually have.
***
## Generate the report
Click **Save View** first. On a brand new view, **Generate Report** stays disabled
until it is saved. If you edit a saved view, the button becomes **Save and Generate
Report** and does both.
Then choose a **Date range**, which offers Last 7 days, Last 30 days, Last 90 days or
a custom range, and generate.
The result opens as a report, titled with the view name and the dates it covers, with
each block showing its record count.
**Export** saves the report as a **PNG image**, not as data. It is for pasting into a
deck or a message. If you need the underlying rows, export from
**[Calls](./call)** instead.
***
## Finding reports again
The **Reports** tab lists every report you have run.
| Column | What it shows |
| - | - |
| **View** | The view it came from. |
| **Date range** | The period it covers. |
| **Status** | Whether the run finished. |
| **Run at** | When it ran. |
Reports do not refresh. Each one is a snapshot. To get current numbers, generate a new
report from the same view.
***
## Where to go next
* Headline numbers without building anything: **[Dashboard](./dashboard)**
* Create the insights worth charting: **[Post-call](./post-call)**
* The underlying calls: **[Calls](./call)**
# Appointment Scheduling
Source: https://docs.fluents.ai/product/features/skills/appointment-scheduling
Let the agent read your real availability, offer times, and book the appointment on your calendar during the call.
**Appointment Scheduling** connects the agent to your calendar. It reads genuine
availability, offers times, collects the details it needs, and books the appointment
before the call ends.
***
## Set it up
Connect your calendar first. The providers offered are **Google Calendar**,
**Microsoft Outlook**, **Cal.com V2**, **GoHighLevel** and **Calendly**.
Then, on the agent's **Basic Information** tab, click **Appointment Scheduling** under
**Choose Skills**.
| Field | What it does |
| - | - |
| **Calendar Provider** | Which connected calendar to book against. Required. |
| **Time zone** | The timezone availability is offered in. Required. |
| **Event Type** | The meeting type to book, such as a 15 minute intro call. Required, and it stays empty until you pick a provider. |
| **Location** | Where the appointment happens. Appears when your event types offer locations. |
| **Collect user's email** | Whether the agent must get an email address before booking. |
**Event Type** reads "Select a calendar provider first" until a provider is chosen.
The meeting types come from your calendar, not from Fluents, so create them there.
The length of an appointment and how far ahead the agent looks are not settable here.
***
## How the conversation goes
The agent only brings up availability if asked. It will not open with your calendar.
When asked generally, it offers the earliest opening rather than reading out a list.
If there are more than a couple of options it asks whether the person has a preferred
time, instead of reciting slots. This keeps the exchange short, which is the
difference between a booking and a hang up.
Once a time is chosen, and only then, it asks for the details it needs. It asks for
everything still missing in one sentence rather than interrogating field by field,
then confirms the booking back.
***
## Collecting an email by voice
Email addresses are where voice booking usually breaks, so the agent handles them
specifically. It reads addresses back in speakable form, saying "at" and "dot" rather
than the symbols, and spells out the part before the domain letter by letter to
confirm it.
Leave **Collect user's email** off if you do not need the address. Every email
collected by voice is a chance to get it wrong, and it adds real time to the call.
***
## Where to go next
* Connect the calendar: **[Google Workspace](/product/integrations/google-workspace)**, **[Outlook](/product/integrations/outlook)** or **[Cal.com](/product/integrations/cal-com)**
* Book the follow up when nobody is available now: **[Call Back Later](./call-back-later)**
* Test the booking flow before you rely on it: **[Testing an agent](/product/features/agent-testing)**
# Call Back Later
Source: https://docs.fluents.ai/product/features/skills/call-back-later
When someone says it is a bad time, let the agent agree a specific time and schedule the callback itself.
**Call Back Later** handles the most common outcome of an outbound call. Someone picks
up, it is a bad moment, and the call is wasted. With this skill the agent notices,
asks when to try again, agrees a time, and schedules the callback without you doing
anything.
***
## Set it up
On the agent's **Basic Information** tab, click **Call Back Later** under **Choose
Skills**. The dialog sets the two messages the agent uses, and both are required.
| Field | What it does |
| - | - |
| **Callback Confirmation (End Call)** | What the agent says once the time is agreed, before hanging up. |
| **Callback Initial Message** | What the agent opens with when it calls back. |
The callback message can use context values, so the default suggestion is along the
lines of `Hi {first_name}, this is {company_name} calling you back. Is now a good time
to talk?`
Write the callback opener as though the person has forgotten agreeing to it, because
they usually have. Naming the company and the reason in the first sentence does more
than any other change here.
Everything below is built in and needs no configuration.
***
## What the agent does
It listens for signals that now is a bad time, such as "I cannot talk right now",
"I am in a meeting" or "call me later". It reassures the person, then asks when they
would prefer to be called.
It accepts two kinds of answer.
**Relative.** "In 45 minutes." "In an hour." "In two and a half hours." It works out
the exact time from the moment of the call.
**A clock time.** "At 9." "Tomorrow at 9:30." "Tuesday at 2:30 Pacific." If the day is
missing it asks. If the timezone is missing it asks, and it accepts everyday names
like Pacific, Central or East Coast rather than demanding a formal one.
Before scheduling anything, it repeats the time back and waits for a yes.
***
## The vague answers people actually give
Callers rarely give a clean time. The agent maps the common vague answers to real ones
and then confirms, rather than guessing silently.
| They say | Agent proposes |
| - | - |
| Morning | 9:00 AM |
| Noon or lunchtime | 12:00 PM |
| Afternoon | 1:00 PM |
| Evening or tonight | 6:00 PM |
| End of day | 5:00 PM |
| A few minutes | 10 minutes from now |
| A range, such as "between 2 and 3" | The start of the range |
If the time they name has already passed today, the agent asks whether they meant
tomorrow.
***
## It will not book you an unsociable call
This is the part worth knowing before you turn the skill on.
The agent avoids scheduling callbacks between **10:00 PM and 8:00 AM** in the person's
local time. If an answer lands in that window without them clearly asking for it, the
agent treats it as a misunderstanding and re-asks using the daytime reading instead.
Someone who says "three" gets read as 3:00 PM, not 3:00 AM, and the agent confirms it.
For "ten" or "eleven" it simply asks which one you meant. It will only book an
overnight callback if the person explicitly asks for one.
This is a good default for consumer calling and a limitation for anyone calling
night shift workers. If you need overnight callbacks, the person has to ask for that
window in so many words.
***
## Where the callback goes
The agreed callback is scheduled as an outbound call from the same agent. It shows up
under **Scheduled** on the **[Calls](/product/features/call)** page, where you can
check it or cancel it before it runs.
***
## Where to go next
* See and manage what is queued: **[Calls](/product/features/call)**
* Hand off to a person instead of rescheduling: **[Call Routing](./call-routing)**
* Get past the screener first: **[Call Screen Handling](./call-screen-handling)**
# Call Routing
Source: https://docs.fluents.ai/product/features/skills/call-routing
Hand a live call to a person when a specific phrase is spoken, either directly or after the agent explains the call first.
**Call Routing** transfers a live call to a phone number when a phrase you choose is
spoken. You write the phrase, you pick who has to say it, and you pick where the call
goes.
***
## Set it up
On the agent's **Basic Information** tab, click **Call Routing** under **Choose
Skills**. The **Configure Call Routing** dialog opens.
Each rule reads as a sentence. **When the** `bot` **says** ``, **Transfer to**
`` **at** ``.
| Field | What it does |
| - | - |
| **When the** | Who has to say the phrase, **bot** or **human**. Defaults to bot. |
| **says** | The phrase that fires the transfer. |
| **Transfer type** | **Direct transfer** or **Warm transfer**. Defaults to Direct. |
| **Transfer to** | A name for the recipient. This is for your reference. |
| **at** | The number the call goes to. |
| **From** / **Until** | Optional. A daily window during which this route may transfer. |
All fields are required except the transfer window. **+ Add more conditions** adds
another rule, and the small **x** on the right removes one.
***
## Transfer windows
**From** and **Until** set a daily window per route. Leave both empty and transfers
happen at any hour. Set them, and a transfer attempted outside the window is blocked.
This is what stops an agent handing a caller to an empty office at nine in the
evening. It is set per route, so a sales line and a support line on the same agent can
keep different hours.
The window is evaluated in the agent's **Timezone**, which you set on
**[Advanced Settings](../agent)**. Set the timezone first, then the window, or you
will be reasoning about the wrong clock.
The dialog currently prints **(Pacific Time)** next to this setting while its own
tooltip says the agent's timezone. The tooltip is the accurate one. If your agent is
not on Pacific time, verify with a test transfer before you rely on the window.
***
## Direct and warm transfers
**Direct transfer** connects the call immediately. The agent says the phrase, the
caller is passed to the number, and the agent drops off.
**Warm transfer** explains the call to the recipient first, then connects the caller.
Direct is the default. Warm costs a few extra seconds but means the person picking up
is not starting cold.
***
## How the phrase is matched
This is the part that surprises people, so it is worth being precise.
The phrase is matched **case insensitively**, and it matches **anywhere inside** what
was said, as long as it sits on whole word boundaries.
That means:
| You configure | Spoken | Fires? |
| - | - | - |
| `transfer to billing` | "Okay, transfer to billing now." | Yes |
| `transfer to billing` | "TRANSFER TO BILLING" | Yes |
| `transfer to billing` | "I will transfer to billings." | No |
| `billing` | "Let me check your billing address." | Yes |
The last row is the trap. A short phrase will fire in conversations you did not
intend, because it only has to appear somewhere in the sentence.
**bot** and **human** rules match identically. Neither one is stricter than the
other. If you have read otherwise, that was wrong.
***
## Choosing a good phrase
Because matching is containment, the phrase does the work of a switch, so treat it
like one.
* **Make it long enough to be deliberate.** "Connecting you to billing now" will not
come up by accident. "Billing" will.
* **Make it something the agent will actually say.** For a **bot** rule, write the
same phrase into the agent prompt and tell the agent when to use it. If the agent
never says it, the rule never fires.
* **Avoid words that appear in the surrounding conversation.** If the agent discusses
billing all call, do not use `billing` as the trigger.
For **human** rules, remember you are matching what the caller says, and callers do
not read your prompt. Short and common is more likely to catch the request, which is
the opposite tradeoff from bot rules and is exactly why false fires happen.
***
## Test before you rely on it
Open **Test Agent** and place a browser or phone call. Say the phrase, or steer the
agent into saying it, and confirm the transfer fires and rings the right number.
Transfers only work on phone calls. A browser test call cannot transfer, so test
routing with **Start Phone Call**.
***
## Where to go next
* Everything else on the agent: **[Agents](/product/features/agent)**
* Build a repeatable test for each route: **[Testing an agent](/product/features/agent-testing)**
* Check whether a transfer actually happened on a call: **[Calls](/product/features/call)**
# Call Screen Handling
Source: https://docs.fluents.ai/product/features/skills/call-screen-handling
Give your agent something to say to the receptionist or assistant who answers before your actual contact does.
**Call Screen Handling** is for the person who answers before your contact does. A
receptionist, an assistant, whoever screens the call. Without this skill an agent
tends to deliver its pitch to the screener, which wastes the call.
***
## Set it up
On the agent's **Basic Information** tab, click **Call Screen Handling** under
**Choose Skills**. Two fields, both required.
**Reason for the call** is what gets shared with whoever is screening. The agent uses
it to explain itself and justify being put through, so write something a receptionist
would accept.
**What to do if the right person isn't available?** is the fallback.
| Option | What the agent does |
| - | - |
| **Request transfer to someone else** | Asks to speak to someone who could help with the same purpose. |
| **Leave a message** | Asks to leave a message, and summarises why it called. |
| **Call back later** | Asks your contact to call back, and gives details for reaching you. |
| **End the call** | Politely ends the call. |
***
## How it behaves
The agent only uses this handling if it actually identifies a screener, and only at
the start of the call. It will not run twice on the same call, and if nobody is
screening, the conversation proceeds normally.
There is one behaviour worth knowing that is not configurable. If the agent learns the
contact is not reachable on this number at all, for example it is simply the wrong
number, it politely ends the call regardless of which fallback you chose.
A vague reason is what makes screeners say no. "Following up on the quarterly
restock order they requested" gets further than "a business matter".
***
## Where to go next
* Handle an automated menu rather than a person: **[IVR Navigation](./ivr-navigation)**
* Book the follow up when your contact is out: **[Call Back Later](./call-back-later)**
* Everything else on the agent: **[Agents](/product/features/agent)**
# End Call
Source: https://docs.fluents.ai/product/features/skills/end-conversation
Give your agent a reliable way to hang up, on closing lines you choose and when it hears the caller wrapping up.
**End Call** controls how your agent hangs up. Without it, an agent can talk past the
natural end of a conversation, because nothing tells it the call is over.
***
## Set it up
On the agent's **Basic Information** tab, click **End Call** under **Choose Skills**.
The dialog sets the closing messages the agent uses before hanging up.
Add one or more **Phrase** entries, using **+ Add more** for each extra one.
Underneath is a checkbox, **Detect when the caller wants to end the call**. It is
**on** by default.
***
## Ending on a phrase
When the agent says one of your phrases, the call ends.
The agent is also told to avoid those phrases unless it means to hang up, and that
these are the only ways the call can be ended. That is what makes the behaviour
predictable.
Matching works the same way it does for **[Call Routing](./call-routing)**. It is case
insensitive, and it matches anywhere inside what the agent said as long as it sits on
whole word boundaries.
Phrases only apply to the **agent**. There is no option to end a call on something
the caller says. That is what the detection checkbox is for.
Pick closing lines the agent would only ever use at the end, such as "Thanks for
your time, goodbye". A short phrase like "goodbye" can appear mid conversation and
hang up on someone.
***
## Detecting when the caller is done
Leave the checkbox on and the agent decides for itself when the conversation is
finished, rather than waiting for a scripted line.
It looks for the caller signalling that they expect the call to end, including
farewells buried inside a longer sentence. "This sounds great, talk to you soon" is
treated as a goodbye.
Phrases give you control, detection gives you coverage. Most agents want both, which
is why detection is on by default. Turn it off only if your agent keeps hanging up
too early.
***
## Where to go next
* Hand off instead of hanging up: **[Call Routing](./call-routing)**
* Schedule a follow up instead of hanging up: **[Call Back Later](./call-back-later)**
* Check how calls actually ended: **[Calls](/product/features/call)**
# In Call Email
Source: https://docs.fluents.ai/product/features/skills/in-call-email
Let the agent send a prepared email during the call, using rules you write for when each one goes out.
**In Call Email** lets the agent email the person while still talking to them. Unlike
a text, the email is not written freehand. You prepare each one in advance and say
when it should be sent.
***
## Set it up
On the agent's **Basic Information** tab, click **In Call Email** under **Choose
Skills**.
First choose an **Email Provider**. The dialog shows whether the one you picked is
**Connected** or **Not Connected**, and lets you connect it without leaving the
page. See **[Google Workspace](/product/integrations/google-workspace)**
or **[Outlook](/product/integrations/outlook)**.
Then add one or more emails, using **+ Add email** for each extra one. Each has four
fields.
| Field | What it does |
| - | - |
| **When should this email be sent?** | The situation that should trigger it, in your words. |
| **From Email** | The address it comes from. |
| **Subject** | The subject line. |
| **Body** | The content of the email. |
You can add several, each with its own trigger, and the agent picks the one whose
condition matches what happened on the call.
***
## Writing the trigger
The trigger is read by the agent, not by a rules engine, so write it as a plain
description of the situation. Something like "When user asks for product details".
The agent is told not to send anything unless a condition is met, and to use only the
details from the email whose condition matched. So a badly separated pair of triggers
is how you end up with the wrong email going out.
Make your triggers clearly distinct from each other. Two that overlap leave the
agent choosing between them, and it may not choose the way you expect.
***
## Personalising the body
The body can include placeholders that are filled from the call's context, so a
prepared email can still carry the person's name, an order number, or anything else
you passed into the call.
***
## The agent needs an address
The agent can only send if it has the person's email address. On an inbound call it
usually does not, so it will ask. If your flow depends on the email arriving, make
sure the agent has a reason to have collected the address by that point.
***
## Where to go next
* Send a text instead, which needs no address: **[In Call SMS](./in-call-sms)**
* Send something after the call rather than during it: **[Post-call](/product/features/post-call)**
* Everything else on the agent: **[Agents](/product/features/agent)**
# In Call SMS
Source: https://docs.fluents.ai/product/features/skills/in-call-sms
Let the agent text the person while still on the phone with them, either freely worded or a message you fix in advance.
**In Call SMS** lets the agent send a text during the call. Useful for the things that
do not survive being read aloud, such as a link, an address or a booking reference.
***
## Set it up
On the agent's **Basic Information** tab, click **In Call SMS** under **Choose
Skills**. The dialog sets the phone number and the message policy.
First pick the **SMS number** the text is sent from. This comes from your numbers, so
you need one before the skill is usable.
Then choose a **Message policy**.
| Policy | What happens |
| - | - |
| **Allow any SMS** | The agent writes the text itself, based on what the conversation needs. |
| **Send a predefined message** | The agent sends exactly the message you write, every time. |
Choosing **Send a predefined message** reveals a box for the message body.
***
## Fixed messages really are fixed
The agent is told it must not alter, add to or replace the wording, and the message is
enforced again when the text is actually sent. It cannot drift.
Use a predefined message for anything with legal or brand wording you cannot let a
model paraphrase. Use **Allow any SMS** when the useful content changes call to
call.
A predefined message can include placeholders that are filled from the call's context,
so a fixed message can still carry a name or an order number.
***
## Limits
Messages are limited to **160 characters**. Write the predefined message to fit, and
expect the agent to keep free-written texts short.
The person's number is taken from the call, so the agent does not need to ask for it
on a phone call.
***
## Where to go next
* Send an email instead: **[In Call Email](./in-call-email)**
* Move the whole conversation to another number: **[Switch Communication](./switch-communication)**
* Everything else on the agent: **[Agents](/product/features/agent)**
# IVR Navigation
Source: https://docs.fluents.ai/product/features/skills/ivr-navigation
Let your agent work through an automated phone menu on the other end, pressing keys until it reaches what you asked for.
**IVR Navigation** lets your agent handle the automated menus it meets when calling
another business. "Press 1 for sales, press 2 for support" is a wall for most voice
agents. This skill lets yours press the key and keep going.
It applies to menus your agent **calls into**. It does not build a menu for your own
inbound callers.
***
## Set it up
On the agent's **Basic Information** tab, click **IVR Navigation** under **Choose
Skills**. Two fields, both required.
**Goal** is what the agent is trying to reach on the other side of the menu. Write it
the way you would tell a person. "Reach the accounts payable department" works better
than "billing".
**Maximum menu selections** is how many menu options the agent may go through before
stopping.
***
## How it behaves
The agent listens to the options, presses the matching key, and keeps track of where
it has been so it does not go in circles. If it reaches a dead end it will try to go
back or start again.
The maximum is the safety net. It stops an agent burning a whole call inside a menu
tree that has no route to your goal.
Menus change. If a route stops working, the menu on the other end probably moved,
and the fix is usually a clearer goal rather than more selections.
***
## Where to go next
* Once through the menu, hand the call to a person: **[Call Routing](./call-routing)**
* Get past a human screener instead of a machine: **[Call Screen Handling](./call-screen-handling)**
* Everything else on the agent: **[Agents](/product/features/agent)**
# Knowledge Search
Source: https://docs.fluents.ai/product/features/skills/knowledge-search
Let the agent look answers up in your knowledge bases mid conversation instead of guessing or inventing them.
**Knowledge Search** lets the agent look something up while it is talking. You point
it at one or more knowledge bases and say what each one covers. When the conversation
touches those topics, the agent searches rather than improvising.
***
## Set it up
Create your content first under **[Knowledge Bases](/product/features/knowledge-base)**.
This one is not in **Choose Skills**. Look for it on the agent's **Data** tab, in the
**Knowledge Bases** section.
Click **Add Knowledge Base** and fill in two fields.
| Field | What it does |
| - | - |
| **Knowledge base** | Which of your knowledge bases to search. |
| **When should this be used?** | The topics it covers, for example `return policies`. |
Add as many as you need.
***
## The second field is the important one
It is easy to treat "When should this be used?" as a label. It is not. It is the
instruction that decides when the agent searches.
The agent is told to reference a knowledge base whenever the conversation turns to the
topics you describe. A description that does not match how customers actually talk
means the agent never searches, and answers from the prompt instead.
| What you write | Result |
| - | - |
| "Return policy, refund windows, exchanges and restocking fees" | Fires when someone asks to send something back. |
| "Docs" | Vague. The agent has no idea when this is relevant. |
Write it as the list of things a customer might ask about, in their words. You are
not naming the document, you are naming the questions.
You can attach several knowledge bases with different topics, and the agent picks
based on what is being discussed.
***
## Where to go next
* Create and fill the content: **[Knowledge Bases](/product/features/knowledge-base)**
* Prove the agent looks things up when it should: **[Testing an agent](/product/features/agent-testing)**
* Everything else on the agent: **[Agents](/product/features/agent)**
# Switch Communication
Source: https://docs.fluents.ai/product/features/skills/switch-communication
Let the agent move the conversation to a phone call when the person cannot keep talking where they are.
**Switch Communication** moves the conversation to a phone call on a number the person
gives. It is for the caller who is on a bad line, on the wrong device, or in a browser
conversation and would rather just be phoned.
***
## Set it up
On the agent's **Basic Information** tab, click **Switch Communication** under
**Choose Skills**. The dialog sets the message the agent uses when switching.
| Field | What it does |
| - | - |
| **Caller Number** | The number the new call comes from. Required. |
| **Switch Communication Message** | What the agent opens with on the new call. |
The suggested opener is along the lines of "Hey, I'm calling you as you requested.
Want to continue where we left off?", which is worth keeping close to. The person
needs to recognise the call immediately.
Phone is the only supported destination today.
***
## How it behaves
When someone asks to continue elsewhere, the agent says whether it can, asks for the
number to use, and reads it back for confirmation before doing anything.
Once the switch is under way it tells the person they can end the current
conversation and carry on with the new one.
It will only do this **once per conversation**. A second request in the same call will
not start another switch.
This is most valuable on the web widget, where someone starts talking in a browser
and would rather be called. On a normal phone call the need is rarer.
***
## Where to go next
* Transfer to a person rather than a new call: **[Call Routing](./call-routing)**
* Send information without moving the conversation: **[In Call SMS](./in-call-sms)**
* Where browser conversations start: **[Web Widget](/product/features/widget)**
# Voices
Source: https://docs.fluents.ai/product/features/voice
Choose how your agents sound, and bring in voices from your own provider account.
**Voices** is the library of voices your agents can speak with. Fluents ships a set,
and you can import more from a provider you have an account with.
***
## The library
The list shows every voice available in this environment.
| Column | What it shows |
| - | - |
| **Provider** | The service the voice comes from. |
| **Name** | The voice name. |
| **Description** | Notes on the voice, if any. |
| **Created By** | Fluents for built-in voices, or your own account for imported ones. |
Filter by **Provider** or by **Created By**, or search by name. Providers are
**Azure**, **Eleven Labs**, **Rime**, **Cartesia**, **Google** and **Gradium**.
***
## Import a voice
Use this when you have cloned or bought a voice on a provider and want an agent to
use it.
Four fields are always there.
| Field | What it does |
| - | - |
| **Provider** | Which service the voice lives on. Required. |
| **Label** | The name you will see in the picker. Required. |
| **Voice ID** | The provider's identifier for the voice. Required. |
| **Description** | A note for whoever picks it later. |
Everything below **Voice ID** changes with the provider. Azure offers **Rate** and
**Pitch**, both defaulting to medium. Eleven Labs offers **Stability**, **Similarity
Boost** and a **Model ID**. Pick your provider first, then fill in what appears.
The **Voice ID** comes from the provider, not from Fluents. The dialog shows an
example of the right shape for whichever provider you pick, such as
`en-US-JennyNeural` for Azure.
***
## Choosing a voice for an agent
Voice is set on the agent's **Basic Information** tab, along with the language and a
**Speed** slider. The play button previews the voice so you can hear it before
committing.
Preview with your own opening line rather than the default. A voice that sounds
right reading a sample sentence can sound wrong reading yours.
***
## Where to go next
* Set the voice on an agent: **[Agents](/product/features/agent)**
* Hear it in a real conversation: **[Testing an agent](/product/features/agent-testing)**
* Write what it says: **[Prompts](./prompts)**
# Webhooks
Source: https://docs.fluents.ai/product/features/webhook
Have Fluents tell your own systems when something happens on a call, without the agent waiting for a reply.
A **webhook** tells your systems when something happens on a call. Fluents sends a
JSON POST to a URL you own, and carries on. Nothing waits for your answer.
Use one to log calls, push transcripts into a warehouse, sync results to a CRM, or
kick off work of your own after a call ends.
***
## Create a webhook
Go to **Webhooks** and click **Create Webhook**.
| Field | What it does |
| - | - |
| **Label** | A name for your own reference. |
| **Subscriptions** | Which events this webhook receives. Required, and you can pick several. |
| **URL** | Where the request goes. Required. |
| **Account Connection** | A connected account, if the endpoint needs one. |
| **Method** | POST. This is the only option for new webhooks. |
Click **Add** to save.
***
## Attach it to an agent
Creating a webhook is not enough on its own. Open the agent, go to **Advanced
Settings**, and add the webhook there.
An agent has **one** webhook. If you need one endpoint for transcripts and another
for post-call results, subscribe the single webhook to both events and branch on the
`type` field at your end.
***
## What you can subscribe to
| Event | Fires when |
| - | - |
| **Phone Call Connected** | A call connects. |
| **Phone Call Did Not Connect** | A call was attempted but never connected. |
| **Phone Call Ended** | A call finishes. |
| **Post-Call Processing Completed** | Analysis of the call is done and results are ready. |
| **Transcript** | Transcript content is available. |
| **Recording** | A recording is available. |
| **Message** | A message is exchanged during the call. |
| **Action** | The agent runs an action. |
| **Human Detection** | The system decides whether it reached a person. |
| **Error** | Something goes wrong during the call or processing. |
**Post-Call Processing Completed** is the one most people actually want. **Phone
Call Ended** fires when the call stops, which is before the insights and results
exist. If you read call results on Ended, they will often be empty.
***
## What arrives
A POST with a JSON body. The top level is consistent across events.
| Field | What it is |
| - | - |
| `call_id` | The call this event belongs to. |
| `type` | The event type, such as `event_transcript`. |
| `from_number` | The calling number. |
| `to_number` | The number called. |
| `is_outgoing` | `true` for outbound, `false` for inbound. |
| `payload` | The event-specific content. |
```json theme={null}
{
"call_id": "00000000-0000-0000-0000-000000000000",
"type": "event_transcript",
"from_number": "+15551112222",
"to_number": "+15553334444",
"is_outgoing": true,
"payload": {
"transcript": "Sample transcript text for this call..."
}
}
```
Only `payload` changes shape between event types. Branch on `type` and read `payload`
accordingly.
***
## Securing your endpoint
Fluents does not sign webhook requests. There is no HMAC and no shared secret, so
your endpoint cannot prove a request came from us. Treat the URL as publicly
reachable by anyone who learns it.
The **Signature Secret** field on **[Actions](./actions)** does not change this. It
is stored and never used.
What to do instead:
* **Put a long random token in the URL** and treat it as the credential.
* **Validate everything** you receive, and ignore anything unexpected.
* **Make handling idempotent**, so a repeated event does not double-charge or
double-book anything.
* **Put your own auth in front** of the endpoint if the systems behind it are
sensitive.
***
## Webhooks or actions
A webhook notifies. An **[action](./actions)** asks a question and waits for the
answer.
If the agent needs to say something based on the response, you want an action. If you
just need your systems to know what happened, you want a webhook.
***
## Where to go next
* Call your API mid-conversation instead: **[Actions](./actions)**
* What post-call processing produces: **[Post-call](/product/features/post-call)**
* Read the calls yourself: **[Calls](/product/features/call)**
* Keys for your backend: **[Get API key](./account/get-api-key)**
# Web Widget
Source: https://docs.fluents.ai/product/features/widget
Put an agent on your website so visitors can talk to it in the browser, with no phone number involved.
The **Web Widget** puts one of your agents on your website. A visitor clicks, talks in
their browser, and the agent answers. No phone number, no dialing.
Each agent has its own widget, so different pages can run different agents.
***
## Where it lives
Open the agent, then **More** at the end of the tab row, then **Web Widget**.
The tab has two options, and which one you want depends on whether the site is a test
or a real product.
| | **Generate JWT** | **API JWT Generation** |
| - | - | - |
| Good for | Testing, landing pages, simple sites | Production |
| What you copy | One token, by hand | An API key your backend uses |
| Tokens are made | Once, by you | On demand, by your server |
***
## Generate JWT
Use this to get something working today.
The **Widget agent** field shows the agent the widget will connect to. It is fixed to
the agent you are editing.
**JWT lifetime** decides how long the token stays valid. Options are 30 minutes,
1 hour, 3 hours, 6 hours and Never expire. The default is 1 hour.
Click **Generate JWT** and copy the token.
**Never expire** is for testing only. A token pasted into a public web page is
readable by anyone who views the source, and one that never expires never stops
being useful to them.
***
## Install it on your site
Paste this immediately before the closing `