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

# Survey Agent

> Asks a caller a short post-call survey after a rep transfers them, and sends the result as webhook events.

The **Survey Agent** is an agent template for surveying **human reps**. After a rep transfers a caller to it, it asks the few questions you configured, such as a satisfaction score or whether the issue was resolved, then says goodbye and ends the call.

There is no survey report page in Telzino. The results go out as [webhook events](https://docs.telzino.com/event-webhooks/events.md#survey) and, optionally, as a push to your CRM (see [Sending results to a CRM](#sending-results-to-a-crm)). The caller speaks the answers, so they are also in the call's transcript (see [Privacy and HIPAA](#privacy-and-hipaa)).

> [!WARNING]
>
> **The rep must transfer the caller.** On NetSapiens, when the rep hangs up, the caller's call ends at the same moment, so there is no way to send the caller anywhere afterwards. So the rep blind-transfers the caller to the survey agent's extension. An AI agent can also hand the caller over.

## How the call works

**1. Intro**

The agent speaks the **Intro** text, which should say the caller is talking to an automated assistant and that the call may be recorded, and then asks the first question.

**2. Questions**

The agent asks the questions in order. A question with an **Only ask when** condition is asked only when the condition holds, and a question with a **Skip when these transfer details are missing** setting is skipped when one of them is unknown on this call. Transfer details in the question text, such as the rep's name, are filled in at the moment the question is asked. When the first question uses transfer details and the lookup is still running after about 3 seconds, the agent reads the introduction first and asks the first question as soon as the lookup finishes, so a rep that is found is always named. Later questions that use transfer details also wait for the lookup.

**3. Closing**

When every question is done, the agent says the **Closing** text and ends the call.

**4. Result**

The result is sent when the call ends, also when the caller hangs up in the middle of the survey. The answers given so far are kept.

During a survey the agent runs only the survey. Pre-call lookups, [Before Call webhooks](https://docs.telzino.com/functions/pre-answer.md) and knowledge-base auto-search are not used on survey agents.

## Counting and cherry-picking

Reps choose whom to transfer, so the results can be biased: a rep can skip the callers who were unhappy. To check, compare the counts. Every survey call that has a saved call record sends exactly one of `survey.completed`, `survey.partial` or `survey.refused`, each with the rep when one was found (see [Rep details](#rep-details); without transferred-call context its `id`, `name` and `extension` are `null`). Compare those events per rep with your PBX's call counts per rep for the same period.

## Caller controls

| The caller | What happens |
| - | - |
| Interrupts a question | The agent stops talking and listens. The opening, the intro followed by the first question, follows the agent's greeting-interruption setting, which is off by default, so callers cannot talk over it |
| Asks to hear a question again ("repeat") | The agent asks it again. It does not repeat a question unless the caller asks or the answer was unclear |
| Asks to skip a question ("skip") | The question is left unanswered and the agent moves on. A skipped **Required** question makes the status `partial`, or `refused` if nothing was answered |
| Says they are done ("I'm done") | The survey ends and the answers given so far are kept |
| Says "don't ask me again" | The survey ends and the result carries the `survey_opt_out` flag (see [Opt-out](#opt-out)) |
| Raises something unrelated to the survey | The agent never tries to solve it. It offers a transfer to the **Off-topic transfer destination** if one is set, or a callback if **Allow off-topic callers to request a callback** is on (**Allow callback** in Connect) |
| Gives a vague answer | The agent asks again once. A score is never guessed. If the second answer still does not fit, the question is left unanswered |
| Gives a number outside the range | Handled as an answer that does not fit: one re-ask, then the question is left unanswered |

## Creating a Survey Agent

Choose **Survey Agent** in the new-agent wizard, in the Dashboard or in Connect. Then pick a starter. Afterwards, turn on transferred-call context for the agent, or the questions have no [rep details](#rep-details):

| Starter | Questions |
| - | - |
| **CSAT (rep)** | A 1 to 5 satisfaction rating for the rep, and a follow-up on what could have gone better when the score is 2 or lower |
| **NPS** | A 0 to 10 likelihood to recommend, and the main reason for the score |
| **First-call resolution** | Whether the issue was resolved, and a callback offer when it was not |
| **Combined (short)** | Resolution, the rep satisfaction rating and an open comment |

The wizard asks for your organization's name (**Company Name** in the Dashboard, **What is the name of your business?** in Connect). It is written into the starter's text where the starter names your business, and you can edit every question afterwards. In the Dashboard, pick the starter and press **Use this starter** before creating the agent. In Connect, pick it in **Starter survey**.

On the agent's settings page, **Reset to starter** replaces the questions, the intro, the closing text and the detractor rule with a starter's, after you confirm. Nothing changes until you save. Your alert and off-topic settings and the target duration are kept. The survey version is kept too, and goes up only when you save a change.

## Settings

The settings are in the **Survey** section of the agent's settings page. The Dashboard and Connect word a few labels slightly differently; where they differ for a whole-survey setting, Connect's wording is given in parentheses. In Connect, each question's fields are labelled "Question n" followed by the field name, for example `Question 1 confirm`; where that field name differs from the Dashboard label, it is given in parentheses too.

| Setting | What it does | Default |
| - | - | - |
| **Intro** | What the agent says first, before the first question. 1 to 500 characters | The starter's text |
| **Closing** | What the agent says when the survey is done. 1 to 500 characters | The starter's text |
| Questions | 1 to 20 questions. Above 5, the page warns that long surveys are often abandoned | The starter's questions |
| **Key** | A short name for the question that appears in the events. Lowercase letters, digits and underscores, starting with a letter, up to 40 characters (`^[a-z][a-z0-9_]{0,39}$`). Unique in the survey | The starter's key |
| **Type** | **Rating** (`rating`): a whole number between a lowest and a highest score, each from 0 to 10. **Yes / No** (`yes_no`). **Choice** (`choice`): 2 to 20 choices of up to 60 characters, each with up to 10 synonyms (**Other ways to say it (comma-separated)**; `choice n synonyms` in Connect). **Open answer** (`open`): free text. Connect labels the options **Yes/No** and **Open** | Rating |
| **Question text** and **Re-ask text (optional)** (`reask`) | What the agent asks, and what it says when it asks again after an unclear answer. Up to 500 characters each | The starter's text |
| **Required** | An unanswered required question makes the status `partial`, or `refused` if nothing was answered at all | On |
| **Confirm the answer** | **Never**, **When unsure** or **Always**. When unsure: the answer fits one value, but the caller hedged or it sounds like another value (for example "for" and "four"), so the agent reads it back first. An answer that fits no single value is asked again, never confirmed | When unsure |
| **Only ask when** (`show only if`) | Ask the question only when an **earlier** question's answer satisfies one condition. For a rating: `==`, `!=`, `<`, `<=`, `>` or `>=`. For yes/no and choice: `==` or `!=`. Open questions cannot be used. Connect shows the operators as words (is, is not, below, at most, above, at least) | Always ask (**None** in Connect) |
| **Skip when these transfer details are missing (comma-separated)** (`skip if missing`) | Comma-separated transfer details such as `transfer.rep.name`, written without braces. The question is skipped when one of them is empty on the call | none |
| **Offer a callback when the answer is yes** (`offers a callback on yes`) | Yes/No questions only. A yes sets the `callback_requested` flag | Off |
| **Detractor rule** (optional) | One condition on a rating, yes/no or choice question. A result that matches it is a detractor (see [Detractor alerts](#detractor-alerts)) | none |
| **Target duration in seconds** (optional) | 15 to 600. A pacing hint only: the agent is told to keep the survey under it. Dashboard only; Connect has no field for it | none |
| **Off-topic transfer destination** | Where an off-topic caller can be transferred. Up to 100 characters. Empty means none | none |
| **Allow off-topic callers to request a callback** (**Allow callback**) | Lets the agent note a callback request from an off-topic caller | On |
| **Send a detractor alert** (**Detractor alert enabled**) | Detractor alerts (see [Detractor alerts](#detractor-alerts)) | Off |
| **Version** | Read-only | |

The intro, closing and question text can use transfer details, for example `{{transfer.rep.name|your representative}}`, which reads "your representative" when the rep's name is not known. See [Transferred-call context](https://docs.telzino.com/functions/transferred-call-context.md) for the variables.

**Multilingual.** When the agent's language is Multilingual, English, Spanish and French text tabs appear. English is required, unless the agent is single-language Spanish or French: then that language is required. A missing translation falls back to English.

**Version.** The version goes up by one on every save that changes the survey, and every event carries it as `survey_version`.

**Preview.** In the playground nobody transfers the call, so transfer details show their fallback wording.

## Detractor alerts

When **Send a detractor alert** is on and a result matches the detractor rule, the alert is sent to every channel you configured. Each channel is sent separately and on a best-effort basis: a failing channel does not stop the others.

| Channel | Setting |
| - | - |
| Email | One address in **Alert email** |
| Slack | An incoming webhook URL starting with `https://hooks.slack.com/` in **Slack webhook URL** |
| Microsoft Teams | A Workflows URL in **Teams Workflows URL** (**Teams workflow URL**). The alert arrives as an Adaptive Card |
| SMS | An E.164 number in **Alert SMS number**. It is sent through the organization's Twilio connection, from the agent's saved Twilio settings; without them the SMS is skipped |

To get the Teams URL:

**1. Open Workflows**

In Microsoft Teams, open **Workflows**.

**2. Pick the template**

Choose the template **Post to a channel when a webhook request is received**.

**3. Choose the channel**

Choose the team and the channel that should receive the alerts.

**4. Copy the URL**

Copy the workflow's URL and paste it in the Teams URL field.

The alert has the same text on every channel:

```plaintext theme={null}
Survey detractor — {agent name}: {question key} = {value} (rep {rep name or 'unknown'}). Call: {transcript_url or 'unavailable'}
```

A yes/no value is shown as `yes` or `no`. The alert has no caller number and no raw or open-ended answer text.

## Sending results to a CRM

Add an [End of Call Action](https://docs.telzino.com/functions/end-of-call-action.md) to the agent. For a survey agent it receives the survey result as JSON after the call ends, and the agent's MCP servers connect for that step only: the live survey never sees your CRM tools. The action can use only the MCP servers' tools, not the agent's other functions such as email or SMS. The result is redacted when PII redaction is on for the organization or for the agent. Webhooks remain the guaranteed way to get the results.

## Opt-out

> [!NOTE]
>
> "Don't ask me again" only sets the `survey_opt_out` flag in the events. Telzino keeps no opt-out list, so partners must honour the flag themselves, by no longer transferring that caller to the survey.

## Privacy and HIPAA

* The answers are spoken, so they are in the call's transcript. The transcript is redacted when PII redaction is on for the organization or for the agent.
* Survey answers are redacted when PII redaction is on for the organization or for the agent (organization PII redaction also defaults on for a [Healthcare Tenant](https://docs.telzino.com/admin-guide/dashboard/customer-management.md)), the same rule as the transcript. With redaction on, the answers in `data` are the redacted text, and the raw and open-ended answers are not sent in `phi` or in the End of Call Action's survey JSON.
* The call record's `session_data.survey` stores only the survey version, the status, which questions were answered and the flags, never the answers. See [Call Logs](https://docs.telzino.com/api-reference/call-logs.md).
* In the events, the caller's number and the raw and open-ended answers go only in `phi`, when the organization allows it. When transcript redaction is on, the redacted text goes in `data`. See [PHI](https://docs.telzino.com/event-webhooks/payloads.md#phi-protected-health-information).
* Transcripts are visible to anyone who can see call logs. In Connect, the AI Agents tab can only be installed for the Super User, Reseller, Office Manager and Call Center Supervisor roles, so ordinary rep logins do not see it. Partners should keep reps away from call logs.

## Rep details

The rep's name, ID, extension and queue come from [Transferred-call context](https://docs.telzino.com/functions/transferred-call-context.md). A new Survey Agent has none of those settings on: in **04 Transfers**, under **Transferred-call context** (in the Dashboard, this is in the Advanced view), turn on at least one (**Trust the Referred-By header**, **Trust the Diversion header**, **Trust the History-Info header**, **Dialed number map** or **Look up the transferring extension in NetSapiens**; in Connect, **Look up the transferring extension in UCaaS**) on the survey agent, or every event has no rep. The NetSapiens lookup needs a NetSapiens integration on **API v2**. When no rep is found, the questions use their fallback wording and `rep.id`, `rep.name` and `rep.extension` are `null`. `rep.source` is `null` when the agent has no transferred-call context setting on, `unknown` when the lookup ran but found no rep, and `internal` after an AI-agent handoff that carried no earlier context.

## Availability

The Survey Agent template is governed through [Feature Administration](https://docs.telzino.com/admin-guide/dashboard/feature-administration.md) as **Survey Agent**. Locking it hides the template in the new-agent wizard and blocks creating one through the API. Survey agents that already exist keep working and stay editable.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.