# CLAUDE Source: https://docs.thoughtly.com/CLAUDE # Mintlify documentation ## Working relationship * You can push back on ideas-this can lead to better documentation. Cite sources and explain your reasoning when you do so * ALWAYS ask for clarification rather than making assumptions * NEVER lie, guess, or make up information ## Project context * Format: MDX files with YAML frontmatter * Config: docs.json for navigation, theme, settings * Components: Mintlify components ## Content strategy * Document just enough for user success - not too much, not too little * Prioritize accuracy and usability of information * Make content evergreen when possible * Search for existing information before adding new content. Avoid duplication unless it is done for a strategic reason * Check existing patterns for consistency * Start by making the smallest reasonable changes ## docs.json * Refer to the [docs.json schema](https://mintlify.com/docs.json) when building the docs.json file and site navigation ## Frontmatter requirements for pages * title: Clear, descriptive page title * description: Concise summary for SEO/navigation ## Writing standards * Second-person voice ("you") * Prerequisites at start of procedural content * Test all code examples before publishing * Match style and formatting of existing pages * Include both basic and advanced use cases * Language tags on all code blocks * Alt text on all images * Relative paths for internal links ## Git workflow * NEVER use --no-verify when committing * Ask how to handle uncommitted changes before starting * Create a new branch when no clear branch exists for changes * Commit frequently throughout development * NEVER skip or disable pre-commit hooks ## Do not * Skip frontmatter on any MDX file * Use absolute URLs for internal links * Include untested code examples * Make assumptions - always ask for clarification # Actions Source: https://docs.thoughtly.com/agents/actions Trigger integrations mid-call so your Thoughtly agent can look up data, write CRM records, send messages, and automate workflows in real time. Trigger integrations mid-call so your agent can look up data, write records, and automate workflows. Add actions to a [Speak node](/agents/nodes#speak-node) to run them mid-call. Add actions from a Speak node by opening **Actions** and clicking **+ Add new action**. Choose an integration, configure it, and reference your [Variables](/agents/variables) inside the action fields. If you have multiple accounts connected for the same integration, select which account to use in the **Account** tab. Actions appear in a compact list view. Hover over an action to reveal the drag handle icon, which lets you reorder actions by dragging. Click anywhere on an action row to edit its configuration. ### Action display names You can set a custom **Display Name** for each action to make your workflow easier to read and maintain. This label appears in the action list and helps you quickly identify what each action does, especially when you have multiple actions of the same type. To set a display name: 1. Click on an action to open its configuration 2. Enter a name in the **Display Name** field at the top of the sidebar 3. The name will appear in the action list instead of the default integration action name If no display name is set, the action shows its default integration name (for example "Send Email" or "Create Contact"). ### Action ID reference Each action has a unique identifier in the format `nodeId.actionId`. You can copy this ID using the copy button in the action header when viewing an action's configuration. Use this ID to reference specific action outputs in variables or outcomes. Actions panel in the Agent Builder ## How mid-call actions change the flow **Without actions:** caller responds -> variables extract -> outcomes evaluate -> next node. **With actions:** the node auto-proceeds without waiting for another caller reply. 1. Agent speaks (Message or Prompt). 2. Action(s) run mid-call (interruptions disabled by default). 3. Variables update from action results. 4. Outcomes evaluate (rule-based outcomes recommended). 5. Next node executes. Because the caller does not speak before outcomes fire, use rule-based outcomes that check action results (for example `lookup_found == true`, `action_status == "ok"`). Prompt-based outcomes do not automatically "see" internal values unless you surface them in the spoken conversation. ## Recommended patterns ### 1) Lookup -> Branch **Goal:** Route based on CRM or API results. * **Action:** CRM or webhook lookup using key fields (phone, email, account ID). * **Variables:** `lookup_found` (boolean), `customer_id` (text). * **Outcomes (rule-based):** * `lookup_found == true` -> enriched path (use variables like `first_name`). * `lookup_found == false` -> collect details before moving on. ### 2) Validate -> Retry loop **Goal:** Ensure a required field is valid before proceeding. * **Action:** Validator or API check (for example email verification). * **Variables:** `email`, `email_valid` (boolean). * **Outcomes (rule-based):** * `email_valid == true` -> next step. * Else -> self-loop to the node asking for email again (limit retries). See [Outcomes -> Loops](/agents/outcomes#loops-special-use-case). ### 3) Book -> Confirm **Goal:** Schedule an appointment during the call. * **Action:** Scheduler integration (calendar, booking tool). * **Variables:** `timeslot_chosen`, `booking_status`. * **Outcomes (rule-based):** * `booking_status == "confirmed"` -> confirmation message then [Transfer](/agents/nodes#transfer-node) or [End](/agents/nodes#end-node). * Else -> offer alternatives or transfer to a human. ```mermaid theme={null} %%{init: {'theme':'base', 'themeVariables': { 'fontSize':'18px'}}}%% graph TD A["📅 Speak Node: Collect Appointment Time"] --> B["⚡ Action: Schedule Appointment"] B --> C{"✓ Check booking_status"} C -->|"✓ confirmed"| D["💬 Speak: Confirmation Message"] C -->|"✗ failed/error"| E["💬 Speak: Offer Alternative Times"] D --> F["✅ Transfer or End Call"] E --> G["☎️ Transfer to Human"] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:4px,color:#000 style B fill:#fff3e0,stroke:#f57c00,stroke-width:4px,color:#000 style C fill:#f3e5f5,stroke:#7b1fa2,stroke-width:4px,color:#000 style D fill:#e8f5e9,stroke:#388e3c,stroke-width:4px,color:#000 style E fill:#ffebee,stroke:#d32f2f,stroke-width:4px,color:#000 style F fill:#e8f5e9,stroke:#388e3c,stroke-width:4px,color:#000 style G fill:#ffebee,stroke:#d32f2f,stroke-width:4px,color:#000 ``` ## Authoring tips * **Interruptions:** Stay disabled by default for mid-call actions to prevent the caller from breaking the integration flow. If you enable interruptions, plan for partial inputs. * **Speak node choice:** Use Message mode for fixed pre/post phrases. Use Prompt mode when the agent must compose dynamic summaries from action results. * **Lean payloads:** Send only the variables you need. Clear, minimal fields reduce errors. * **Preface long actions:** Add a short line like "One moment while I check that" before triggering an action to set caller expectations. * **Structured outputs:** Set predictable fields (such as `action_status = "ok"` or `"error"`) to simplify rule checks. ## Error handling and resilience Design outcomes for real-world hiccups: * **Happy path:** `action_status == "ok"` will proceed. * **Recoverable:** `action_status == "error"` will retry * **Fallback:** persistent failure -> transfer to a human or offer a call-back. * **Timeouts:** if an action exceeds your expected SLA, branch to a graceful message and continue. Action error handling pattern **Caller experience guardrails** * Use **Uninterrupted message** for pre-action instructions so the agent is not cut off mid-sentence. * For actions that take several seconds, add a short progress update after a couple of seconds to reduce perceived wait time. ## Data flow and variables * Action outputs can set or update [Variables](/agents/variables) such as `customer_id`, `plan`, or `lookup_found`. * These values are immediately available to rule-based outcomes in the same node. * If you need AI to summarize results, surface key values verbally in a Prompt speak node after the action completes. ## Setup checklist (quick start) * [ ] Open a [Speak node](/agents/nodes#speak-node) * [ ] Click **Add action** and choose an integration * [ ] Select which account to use (if you have multiple accounts for the same integration) * [ ] Configure fields (URL, method, headers, body) * [ ] Map your [Variables](/agents/variables) to action inputs * [ ] Add rule-based [Outcomes](/agents/outcomes) that check action results * [ ] Test the flow using [Test Agent](/agents/testing) * [ ] Review action logs and outputs * [ ] Verify error handling branches are in place ## Common mistakes to avoid * Relying on prompt-based outcomes immediately after actions; they cannot see internal flags unless you speak them. * Skipping error branches or default outcomes, which can stall the flow. * Forgetting to cap retries or offer a human hand-off. * Fetching more data than you need. * Re-enabling interruptions and losing action results mid-flow. ## See also * [Speak nodes](/agents/nodes#speak-node) - where actions live. * [Variables](/agents/variables) - read and write values used by actions and rules. * [Outcomes](/agents/outcomes) - build deterministic branches after actions. * [Transfer node](/agents/nodes#transfer-node) - escalate on errors or high intent. # Call screening bypass Source: https://docs.thoughtly.com/agents/call-screening-bypass Configure outbound voice agents to detect and respond to call-screening prompts like name and reason gates so they reach a live person every time. Call screening bypass helps a Thoughtly voice agent handle automated screening prompts at the start of outbound calls. When a screening service asks who is calling, which company they represent, or why they are calling, the agent can respond before continuing the normal conversation flow. This is useful for outbound teams that call contacts who use phone screening, spam protection, virtual receptionists, or device-level call filters. Call screening bypass helps agents respond to screening prompts. It does not guarantee that every carrier, device, app, or receptionist will connect the call. ## How it works When enabled, the agent begins with a short screening stage before the main conversation. During that stage, it listens for screening prompts and answers with the information you configure. Typical screening prompts include: * “Who is calling?” * “What company are you calling from?” * “What is the reason for your call?” * “Please state your name after the tone.” After the screening interaction completes and the recipient answers, the agent continues into the normal start node or call flow. ## Setup fields Configure screening responses with clear, short values: | Field | Description | Example | | ------------------ | -------------------------------------------------------- | ------------------------------------------ | | Agent name | The name the agent should give when asked who is calling | “Ava” | | Company name | The business represented by the agent | “Acme Home Services” | | Reason for calling | A concise reason that sounds natural to the recipient | “following up on your appointment request” | ## Writing a good reason for calling Keep the reason specific, truthful, and short. Good examples: * “following up on your quote request” * “calling about your upcoming appointment” * “returning your request for more information” Avoid vague or spammy phrasing: * “important business matter” * “urgent opportunity” * “please answer this call” ## Testing To test call screening bypass: 1. Enable screening bypass on the agent or phone number where available. 2. Place a test call to a number that uses call screening. 3. Review the call transcript in [History](/platform/history). 4. Confirm the screening response is accurate and the agent continues the main flow after connection. ## Relationship to branded calling Call screening bypass and branded calling solve different trust problems: * **Call screening bypass** helps the agent answer automated screening prompts. * **Branded calling** helps the recipient see a verified business name or identity on supported carriers/devices. Use both when available for high-volume outbound workflows. # Deploy a voice agent Source: https://docs.thoughtly.com/agents/deployment Publish your Thoughtly voice agent, assign a phone number, and start handling inbound calls or launching outbound campaigns in production. ## Deploying your first Voice Agent Now that you've [built your Voice Agent](/agents/overview), it's time to deploy it and start making calls. Inbound deployment is quite different from outbound deployment, so we'll cover both here. Simply put, inbound calls can be easily handled by connecting a phone number, while outbound calls often require the use of [Automations](/automations/getting-started) to trigger the call. ## Inbound Deployment Inbound deployment is the process of connecting a phone number to your Voice Agent so that it can receive calls. You can either buy a new phone number from Thoughtly or forward calls from your existing phone number to your Voice Agent. ### Methods Below are the two methods for inbound deployment. Choose the one that best fits your needs and read the corresponding documentation to get started: 1. **[Buying phone numbers](/phone-number/getting-started)**: Purchase a new phone number from Thoughtly and connect it to your Voice Agent. This is the easiest way to get started– all you have to do is share your new phone number with customers. 2. **[BYOC - Bring Your Own Carrier](/phone-number/byoc)**: Purchase new numbers or import existing numbers from Twilio/Telnyx carriers. You can also forward calls from your existing phone number to your Voice Agent. ## Outbound Deployment Outbound deployment is the process of making calls from your Voice Agent. You can use Automations to trigger outbound calls based on certain conditions, such as a new lead being added to your CRM. ### Recommended Prerequisites Before you deploy your Voice Agent, we recommend that you complete the following steps: 1. **Voicemail**: If you plan on making outbound calls, you may want to set up [Voicemail](/agents/settings#voicemail) to leave a message if the call goes unanswered. 2. **Automations**: If you plan on making outbound calls, you'll need to set up [Automations](/automations/getting-started) to trigger those calls. Make sure to read the [Automations documentation](/automations/getting-started) to get started. 3. **Phone Numbers**: If you plan on making outbound calls, you'll need to have a phone number connected to your Voice Agent. You can either [buy a new phone number](/phone-number/getting-started) or use an existing one. ## SMS In addition to making and receiving calls, your Voice Agents can also send and receive SMS messages. This can be a powerful tool for customer engagement, especially when used in conjunction with your Voice Agent on phone calls. SMS messages can be sent during calls or as part of automation workflows using the [Send SMS action](/automations/actions#messaging-and-inbound). You can send text messages to share links, collect information, or provide additional context. SMS can also be used to follow up with customers after the call has ended, or if the call was missed, by using [Automations](/automations/getting-started). # Migrate legacy agents to v1.8 Agent Builder Source: https://docs.thoughtly.com/agents/migration-guide Step-by-step guide for rebuilding legacy v1 free-form Thoughtly agents in the v1.8 node-based Agent Builder with parity for prompts, actions, and flows. **v1 agents were retired on February 16, 2026.** v1 agents are no longer supported. If you haven't migrated yet, follow this guide to rebuild your agent in v1.8 as soon as possible. This guide walks you through rebuilding a legacy **v1 "free-form"** agent in the **v1.8 [Agent Builder](/agents/overview)**. *** ## The migration mindset **v1** let builders "jump around" with rules and loosely structured prompts. **v1.8** is more structured: * You build a conversation as a graph using **four node types**: [Start](/agents/nodes#start-node), [Speak](/agents/nodes#speak-node), [Transfer](/agents/nodes#transfer-node), [End](/agents/nodes#end-node). * **Speak** is split into two variants: * **Message** (fixed wording, can be verbatim). * **Prompt** (adaptive instructions, like a mini playbook). * [Outcomes](/agents/outcomes) decide where the conversation goes next (and are where "rules" belong now). Unlike in **v1**, outcomes in **v1.8** agents are more strict. The agent will not jump from the first node to the last. This allows for more robust workflows while keeping flexibility. * [Variables](/agents/variables) capture structured data *right after the caller replies and before outcomes evaluate* so outcomes can branch on fresh values. * [Actions](/agents/actions) run integrations mid-call and change flow timing. *** ## v1 to v1.8 mapping (quick translation table) | v1 concept | v1.8 replacement | Notes | | ----------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | "Opening script" | [**Start node**](/agents/nodes#start-node) | Start is spoken exactly as written; great for consent/compliance lines. | | Mixed "message/prompt" block | [**Speak -> Message**](/agents/nodes#speak-node) or [**Speak -> Prompt**](/agents/nodes#speak-node) | Use **Message + Repeat verbatim** for exact lines; use **Prompt** for dynamic responses. | | Rule-heavy branching | [**Outcomes**](/agents/outcomes) | Use **rule-based outcomes** for deterministic branching; **prompt-based outcomes** for intent classification. | | "Ask question + parse answer" via rules | [**Variables**](/agents/variables) | Variables extract before outcomes; define clear extraction instructions. | | "Jump anywhere", use rules for navigation | **Explicit node connections + loops** via [Outcomes](/agents/outcomes#loops-special-use-case) | Use outcomes + loop patterns for retries/clarification. | | Knowledge stuffed in prompt/rules | [**Genius knowledge base**](/genius/getting-started) + [attach to agent](/genius/agent-binding) | Strongly prefer Q\&A formatting for retrieval speed and accuracy. | *** ## Step-by-step migration process ### Step 1: Inventory your v1 agent (before you touch v1.8) Create a quick "agent spec" from the v1 setup: * Primary goal (qualify, schedule, support, collections, and so on). * Required **verbatim** lines (consent, disclaimers, identity statements) using [Start](/agents/nodes#start-node) or Speak -> Message in [Speak nodes](/agents/nodes#speak-node). * Your **major branches** (happy path, objections, voicemail/no-answer, escalation) mapped to [Outcomes](/agents/outcomes). * What data you capture, **if any** (name, email, intent, budget, eligibility) as [Variables](/agents/variables). * Which integrations you hit, **if any** (CRM lookup, scheduler, webhook, ticketing) as [Actions](/agents/actions). This becomes your blueprint for the v1.8 flow. *** ### Step 2: Rebuild the skeleton with nodes In v1.8, every agent starts with [Start (step 0)](/agents/nodes#start-node) and then flows through numbered nodes (step 1, 2, 3). These step numbers show up during [Testing](/agents/testing) and can be referenced later. Recommended skeleton: 1. **Start**: tight opener (+ verbatim compliance line if needed). 2. **Speak (Prompt)**: what the agent is supposed to say. Do not put too much text in a single node; if it makes sense, split it. See [Speak nodes](/agents/nodes#speak-node). 3. Branch to a few "big rocks" (for example Qualified / Not qualified / Objection / Transfer) using [Outcomes](/agents/outcomes). 4. **End** nodes for each major ending state (success, voicemail, no-match) using [End nodes](/agents/nodes#end-node). *** ### Step 3: Convert v1 "rules" into outcomes (your new routing layer) [Outcomes](/agents/outcomes) decide **where the conversation goes after a node**. Use this rule of thumb: * **[Prompt-based outcomes](/agents/outcomes#prompt-based-outcomes-ai)**: when you need natural-language classification ("is this an objection?", "are they interested?", "did they ask pricing?"). * **[Rule-based outcomes](/agents/outcomes#rule-based-outcomes-deterministic)**: when you have **Variables** or [Action](/agents/actions) flags and want deterministic logic (recommended after actions). **Migration pattern (common):** * v1: "If user sounds qualified, go to scheduling; else ask more questions." * v1.8: Speak node -> prompt-based outcomes: * "User said *something* that qualifies them" -> scheduling branch. * "User did not say *something* that qualifies them" -> clarification branch. * Default -> fallback / transfer. **OR** * v1.8: Speak node -> extract [Variables](/agents/variables) -> rule-based outcomes: * `qualified == true` -> scheduling branch. * `qualified == false` -> clarification branch. * Default -> fallback / transfer. Loops are a first-class pattern for retries and clarification. Use them deliberately and cap retries. See [Loops](/agents/outcomes#loops-special-use-case). *** ### Step 4: Replace "parsing via rules" with variables [Variables](/agents/variables) are how you capture structured data for: * branching in [Outcomes](/agents/outcomes), * inputs to [Actions](/agents/actions), * post-call workflows in [Automations](/automations/getting-started). Key behavior to design around: * Variables extract **immediately after the caller reply and before outcome evaluation**. * You can choose **Current speak node** vs **Conversation history** in [Variables](/agents/variables). * Re-visiting a node can **re-extract and overwrite** previous values (useful for confirmation loops). *** ### Step 5: Migrate integrations to Actions (mid-call) In **v1**, the only supported mid-call action was **Calendly scheduling**, and it was tightly coupled to rules and implicit flow behavior. In **v1.8**, scheduling is handled through a **new mid-call [Actions](/agents/actions) framework**, with explicit Speak nodes, [Variables](/agents/variables), Actions, and [Outcomes](/agents/outcomes). Because this is both the **only overlapping mid-call capability** between v1 and v1.8 and the most structurally different, scheduling migration is covered in a dedicated guide. Continue here: **[Scheduling in v1.8 (Agent Builder)](/resources/agent-scheduling)** For action details, see **[Calendly](/integrations/scheduling/calendly)** and **[Cal.com](/integrations/scheduling/cal-com)**. **Important:** v1 scheduling logic cannot be ported directly. It must be rebuilt using v1.8 patterns (Variables -> Actions -> rule-based Outcomes). Attempting to replicate v1 rule-based scheduling will lead to brittle or broken flows. *** ### Step 6: Move "knowledge inside prompts" into Genius (recommended) If your v1 agent depended on long prompt/rules to answer FAQs, move that into [Genius](/genius/getting-started): * Keep content in **Q\&A format** (faster retrieval, better matching). * Attach the Genius knowledge base to the agent via [Settings -> Genius tab](/agents/settings#genius-tab) or the [Genius binding guide](/genius/agent-binding). *** ### Step 7: Recreate global behavior in Settings (do not bury routing here) Use [Settings -> Advanced prompt](/agents/settings#advanced-settings) for persona, tone, and guardrails -- **not navigation logic**. Also migrate/tune: * **Voice and Language** in [Settings](/agents/settings#main-settings). * **Presence tuning** (silence timeout; adjust endpointing, sensitivity, retries) in [Settings -> Presence tab](/agents/settings#presence-tab). * **Voicemail** (keep the message short, avoid sensitive info) in [Settings -> Voicemail](/agents/settings#voicemail). *** ### Step 8: Test like the v1.8 docs recommend (text first, then voice) Use both built-in testing modes: * **[Test Agent (text chat)](/agents/testing#test-agent-text-chat)**: fastest for checking outcomes, variables, and action flags. * **[Call Me (real call)](/agents/testing#call-me-real-call)**: validate TTS, barge-in, endpointing/latency, transfers, and action timing. *** ### Step 9: Cutover (deployment + phone number assignment) When you are ready to replace v1: * Assign the appropriate phone number profiles (inbound/outbound/SMS) to the new v1.8 agent. See [Deployment](/agents/deployment) and [Phone Number Configuration](/phone-number/configuration). *** ## Common migration pitfalls (and how to avoid them) * **Using Prompt when wording must be exact** -> use **Message + Repeat verbatim** (or [Start](/agents/nodes#start-node)). * **Branching after an Action with prompt-based outcomes** -> use **rule-based outcomes** that check [Action](/agents/actions) flags/results. * **Vague variable extraction instructions** -> use explicit constraints + "do not invent values" in [Variables](/agents/variables). * **Special characters being spoken aloud** -> add the "no special characters" instruction to the [Advanced prompt](/agents/settings#advanced-settings) (global fix). * **Relying on legacy post-call** -> migrate workflows to [Automations](/automations/getting-started) (recommended by docs). ## See also * [Nodes](/agents/nodes) - Start, Speak, Transfer, End. * [Outcomes](/agents/outcomes) - routing and loop patterns. * [Variables](/agents/variables) - extraction and validation. * [Actions](/agents/actions) - mid-call integrations. * [Settings](/agents/settings) - voice, presence, and advanced prompt. * [Testing](/agents/testing) - Test Agent and Call Me. * [Deployment](/agents/deployment) - go live with phone numbers. * [Genius](/genius/getting-started) - knowledge base setup. # Node types in the Agent Builder Source: https://docs.thoughtly.com/agents/nodes Reference for every node type in the Thoughtly Agent Builder, including message, decision, action, transfer, and end nodes that shape conversation flow. Thoughtly agents use four node types: **Start**, **Speak**, **Transfer**, and **End**. Use the canvas toolbar at the bottom center of the screen to manage nodes and organize your flow. Each node is automatically assigned a sequential step number that helps you track conversation flow during testing and call replay. The Start node is always step 0, and subsequent nodes are numbered sequentially (1, 2, 3, etc.). These step numbers appear in the UI, test logs, and when referencing node responses in variables. Available node types in the Agent Builder ## Canvas toolbar The canvas toolbar appears at the bottom center of the Agent Builder and provides quick access to common actions: * **Auto-organize** - Automatically arranges nodes in a clean, readable layout * **Duplicate** - Clones the selected node with correct positioning (requires a node to be selected) * **Delete** - Removes the selected node and its connected edges (requires a node to be selected) * **Add Node** - Opens a menu to create new nodes: * **Speak** - Creates a speak/question node * **Transfer** - Creates a transfer\_action node * **End** - Creates an end node The Duplicate and Delete buttons are only enabled when you have a node selected on the canvas. ## Start node **What it does:** Opens the conversation. Whatever you write here is the first thing your caller hears. **Guidelines** * Keep it short and attention grabbing. * Use plain language; avoid jargon. * Proofread carefully; content in **Start** is repeated verbatim. **Tips** * If you need legal or opt-in wording, keep it here so it is always delivered the same way. * Consider referencing [Variables](/agents/variables) for simple personalization (for example, the caller's first name), but test pronunciation with [Call Me](/agents/testing#call-me-real-call). Everything in the Start node's **Message** field is spoken exactly as written. Double-check spelling, punctuation, and acronyms. ## Speak node Speak node configuration panel **What it does:** Drives the conversation. Speak nodes decide what the agent says, how it says it, and when it moves on. Speak nodes come in two variants: **Message** and **Prompt**. ### 1) Message speak node * **Use when:** You want the agent to say a specific line (short answer, confirmation, compliance statement) with minimal variation. * **Behavior:** The agent speaks the text you provide, using context only to keep tone natural. * **Speech settings:** Click the gear icon in the message header to access speech options: * **Verbatim:** Say exactly what is written every time (just like the [Start node](#start-node)). Ideal for consent or disclaimers. * **Uninterrupted:** Prevents the caller from interrupting. Useful for longer instructions or critical copy. * **Spell Numbers:** Improves pronunciation of long numbers such as order IDs or confirmation codes by reading them digit-by-digit. Pair with [Phone numbers](/phone-number/getting-started) and other numeric data. * **Good for:** Simple Q\&A, confirmations, disclaimers, short instructions. A blue indicator dot appears on the settings icon when any speech setting is active, making it easy to see which nodes have special configurations. ### 2) Prompt speak node * **Use when:** The agent must compose a response using multiple pieces of information (purchase details, caller info, integration outputs, dynamic Q\&A). * **Behavior:** Treat the field as instructions for how the agent should respond. Think mini playbook, not a fixed script. * **Speech settings:** Click the gear icon in the message header to access speech options: * **Uninterrupted:** Prevents the caller from interrupting. Useful for longer instructions or critical copy. * **Spell Numbers:** Improves pronunciation of long numbers by reading them digit-by-digit. * Note: **Verbatim** is not available in Prompt mode by design; prompts stay adaptive. * **Authoring tips** * Write in the order: goal -> constraints -> must-say points -> tone. Keep it concise. * Reference data via [Variables](/agents/variables) such as CRM fields or custom attributes. * Specify the delivery channel if it matters ("Keep under 160 characters for SMS."). * End with a clarity cue such as "Keep it short and concise." * **Pro tip:** Frontier models (GPT-5, Gemini 2.5, and similar) are great at drafting first-pass prompts. Ask for a proposal, then adapt it inside your Prompt speak node. ## Early summaries End nodes and Transfer nodes can generate a summary before the call ends or transfers. Early summaries are useful when another system or human needs context immediately instead of waiting for normal post-call processing. When enabled: * The summary is generated before the final hangup or transfer. * Downstream systems can retrieve the summary using the call or interview response identifier where supported. * Warm transfers can include context for the receiving team. Use early summaries for live handoffs, urgent support workflows, or integrations that need immediate post-call context. ## Transfer node Transfer node configuration panel **What it does:** Hands the caller to a human or another agent. Transfer nodes offer two modes: ### 1) Phone Router * Transfers the caller to a specific [Phone number](/phone-number/getting-started). * Optional pre-transfer **Message** lets the agent speak before the hand-off. * The transfer occurs immediately after that message (if present). * Phone numbers are validated in real-time using country-aware formatting rules to prevent transfer failures. * Optional **Extension** field allows you to specify an extension number for the transfer destination. Content in the Phone Router **Message** is spoken exactly as written. Proofread it before publishing. **Phone number validation** * The system automatically validates phone numbers based on the selected country's formatting rules. * Validation appears after you enter 7 or more digits. * Leading and trailing whitespace is automatically trimmed to prevent invisible character issues. * You can use [Variables](/agents/variables) in the phone number field; validation is bypassed when variables are present. * Invalid phone numbers will show an error message and prevent the node from being saved until corrected. Use the country dropdown to ensure your phone number is validated against the correct country's format. The system supports international phone numbers with proper country codes. **Extension field** * The **Extension** field supports both static text and dynamic [Variables](/agents/variables). * Use the bolt icon (⚡) to insert variables such as `{{system.contact.email}}` or custom extracted data. * Variables appear as styled chips in the field for easy identification. * Extension values are sent to the destination phone system after the call is connected. ### 2) Agent Transfer * Connects the caller to another [Agent](/agents/overview) in your account with no extra setup. * Select the target agent from your list; the current agent session ends when the transfer begins. * Optional pre-transfer **Description** lets you customize what the agent says before the hand-off (defaults to "Transferring you to \[agent name] now"). * Ideal for warm hand-offs or specialist escalation after identity verification or form capture. **When to use Transfer** * Call routing after qualification. * Escalation to a specialist team. * Warm hand-offs after identity verification or form capture via [Actions](/agents/actions). ## End node **What it does:** Closes the conversation gracefully and hands control back to any downstream [Automations](/automations/getting-started). **Guidelines** * Keep the goodbye short and courteous. * Use consistent endings across flows to reinforce brand tone. * Create multiple **End** nodes to close different branches (success, voicemail, no-match). Content in the End node's **Message** is spoken exactly as written. Review it for accuracy. ## Quick decision guide * **Fixed line that must be exact?** -> Use **Start** or Speak > **Message** with **Repeat verbatim**. * **Adaptive response using data or context?** -> Use Speak > **Prompt**. * **Need to hand off?** -> Use **Transfer** (Phone Router or Agent Transfer). * **Conversation finished?** -> Use **End**. ## Common mistakes to avoid * Putting long scripts in **Start**; keep the opener tight. * Using **Prompt** when an exact line is required; select **Message** + **Verbatim** instead. * Forgetting to enable **Uninterrupted** for critical information. * Skipping pronunciation checks; turn on **Spell Numbers** for IDs, order numbers, or [Phone numbers](/phone-number/getting-started). * Missing the speech settings icon; click the gear icon in the message header to access all speech options. ## See also * [Variables](/agents/variables) - personalize messages safely and branch on captured data. * [Phone Numbers](/phone-number/getting-started) - formatting, country codes, and testing. * [Agents](/agents/overview) - creating, naming, and organizing agents. * [Outcomes](/agents/outcomes) - routing logic after Speak nodes. * [Actions](/agents/actions) - mid-call work, lookups, and best practices. # Outcomes and conversation branching Source: https://docs.thoughtly.com/agents/outcomes Define outcomes that decide where a Thoughtly voice agent routes the conversation after each caller response, enabling dynamic branching and follow-ups. **Prerequisites**: Complete [Agent Builder Overview](/agents/overview) and [Nodes](/agents/nodes) first. Outcomes tell your agent **where to go next** after a caller speaks. Clear outcomes mean smooth navigation; think of them as written playbooks that ensure your agent always knows what to do. Add outcomes from the right panel of a [Speak node](/agents/nodes#speak-node). Open the node, scroll to **Outcomes**, and click **Add outcome**. Outcome configuration panel There are two outcome types: 1. **Prompt-based outcomes** (AI decides) 2. **Rule-based outcomes** (deterministic checks) A node can use either prompt-based or rule-based outcomes, not both. Pick the mode that fits the scenario. ### Comparison: Prompt-based vs Rule-based | Feature | Prompt-based | Rule-based | | ---------------------- | ----------------------------------- | ------------------------------- | | **Decision Maker** | AI interprets intent | Exact logical conditions | | **Best For** | Open-ended replies, varied phrasing | Structured data, yes/no answers | | **Accuracy** | Flexible interpretation | 100% deterministic | | **Setup Complexity** | Write clear labels | Define logical rules | | **Maintenance** | Rename labels to clarify | Reorder rules carefully | | **Ambiguity Handling** | Interprets closest match | Requires exact match or Else | | **Use Case** | "Interested or not?" | "Email valid? Budget > \$250k?" | | **Compliance** | ⚠️ Not recommended | ✅ Required for critical paths | ## Prompt-based outcomes (AI) **What it does:** After the caller responds, Thoughtly evaluates the reply with AI and selects the best matching outcome. **When to use:** * Interpreting open-ended replies (interest level, objections, next-step intent) * Handling varied phrasing where exact keywords are unpredictable Prompt-based outcome configuration **How to write great outcomes:** * **Be distinct.** Avoid overlapping labels such as "Positive" and "Very positive." * **Be concrete.** Prefer "Wants appointment" over "Positive answer." * **Be short.** Aim for 12-50 characters or one to two short sentences. * **Cover common branches.** Skip tiny variations that sound the same. **Common Mistake**: Using overlapping outcome labels like "Positive" and "Very Positive." The AI may struggle to distinguish them. Instead, use concrete labels: "Wants to book" vs "Interested, needs info." **Example set:** * Wants to book now * Interested, send SMS link * Not interested * Busy - call back later **Testing prompt outcomes:** 1. Draft three to five sample caller replies for each outcome. 2. Run test calls or the simulator and observe which path is chosen. 3. If outcomes collide, rename them to be more specific and retest. Prompt outcomes pair best with a [Prompt speak node](/agents/nodes#2-prompt-speak-node), where your prompt already frames the agent's intent and tone. ## Rule-based outcomes (deterministic) **What it does:** After the caller responds (or after an [Action](/agents/actions) runs), the system checks your rules from top to bottom and takes the first match. No AI is involved. **When to use:** * Branching based on structured info (yes/no answers, numbers, captured email) * Navigating after Actions (lookup results, API flags, form validation) * Enforcing critical logic where ambiguity is risky (compliance, verification, eligibility) Rule-based outcome ordering **How it is evaluated:** * Outcomes are checked **from top to bottom** in the order you arrange them * The **first matching rule wins** and routes to its connected node * All subsequent rules are skipped once a match is found * Always add a final **Else** (default) outcome to catch anything that doesn't match **Reordering outcomes:** Hover over an outcome to reveal the drag handle icon. Click and drag to reorder outcomes. For rule-based outcomes, edge connections automatically update to reflect the new order. Rule outcomes showing A, B, C branching to different nodes **Example: Email validation flow** In the screenshot above, outcomes are evaluated top-to-bottom: **Outcome A** (checked first)\ Rule: `caller_said_stop == true`\ → Routes to: **End node** (conversation terminates) **Outcome B** (checked second, only if A fails)\ Rule: `email_is_valid == true`\ → Routes to: **Collect address details** (next step in happy path) **Outcome C** (checked third, acts as Else/Default)\ Rule: Always matches if A and B both failed\ → Routes to: **Clarify budget** (fallback to gather more info) **Why order matters:** If you swap A and C, the "Clarify budget" path would always execute first (since Else always matches), and the agent would never check if the caller said stop. **Common Mistake**: Forgetting the Else/Default outcome in rule-based routing. Always add a fallback to handle unexpected inputs or the agent will get stuck. **Logic safety checklist:** * Are rules mutually exclusive where needed? * Is the most specific rule above the general ones? * Do you have a final Else/Default outcome? * Did you test negative and no-input cases? ## Loops (special use case) You can loop an outcome back to the same node. * Keep answering questions until the caller is satisfied. * Re-ask or verify required information such as email or budget. **Simple Q\&A loop (Prompt + prompt outcomes):** 1. Speak node -> Prompt: "Answer the caller's questions clearly and concisely. If the caller asks a new question, continue; if not, proceed." 2. Add two prompt-based outcomes: * Caller asked a question -> connect back to this node (self-loop) * No more questions -> go to the next step 3. Test with varied phrasing to confirm the loop works. Add a maximum loop count or a fallback branch to avoid infinite loops. For required fields, pair the loop with rule checks (for example `email_is_valid == false`) so the agent retries with a clarifier or offers a [Transfer](/agents/nodes#transfer-node). ## Troubleshooting **Outcomes not triggering correctly** * Verify outcome type matches your use case (prompt for open-ended, rules for structured) * Check that outcome labels are distinct and specific * Test with varied caller responses using [Test Agent](/agents/testing) **Agent gets stuck at a node** * Ensure rule-based outcomes have an Else/Default path * Verify all conditions are achievable (not logically impossible) * Check that prompt outcomes have at least 2-3 options **Wrong outcome chosen (prompt-based)** * Rename outcomes to be more specific and concrete * Add more example phrases in your testing * Consider switching to rule-based if logic is too complex **Rule order issues** * Remember: first match wins in rule-based outcomes * Move specific rules above general ones * Test all branches with [Test Agent](/agents/testing) ## Common mistakes to avoid * **Vague labels**: Using "Positive" instead of "Wants to book now" in prompt mode * **Missing Else**: Forgetting the default fallback in rule-based outcomes creates [dead ends](/resources/glossary#dead-end) * **Wrong order**: Placing general rules before specific ones causes incorrect matches * **Compliance risk**: Using prompt outcomes for legal/medical/financial decisions where exactness matters ## See also * [Speak nodes](/agents/nodes#speak-node) - choose Message vs. Prompt * [Actions](/agents/actions) - mid-call steps that set flags and values * [Variables](/agents/variables) - capture data for branching logic * [Transfer node](/agents/nodes#transfer-node) - escalate to humans or other agents * [End node](/agents/nodes#end-node) - finish conversations cleanly * [Testing](/agents/testing) - validate outcome logic with Test Agent * [Glossary: Happy Path](/resources/glossary#happy-path) - designing the ideal conversation flow # Agent Builder overview Source: https://docs.thoughtly.com/agents/overview Design, test, and launch conversational voice agents with the Thoughtly Agent Builder — a visual node-based editor for prompts, actions, and outcomes. Agent Builder workspace **Prerequisites**: Complete [Introduction](/getting-started/introduction) and [Quick Start](/getting-started/quick-start) first. Welcome to the Agent Builder. This is where non-technical teams design, test, and launch [conversational agents](/resources/glossary#voice-agent) that sound natural and get work done. ## What you can build * Voice agents that open calls, answer questions, qualify leads, book meetings, and transfer to people when needed * Consistent, brand-safe scripting with adaptive AI where it helps and deterministic rules where it matters most ## How the builder is organized Thoughtly Agent Builder workspace * **Nodes and their types** - The building blocks of a flow: Start, Speak (Message/Prompt), Transfer, End * **Outcomes** - Decide where to go next after each turn (AI prompt-based or deterministic rule-based) * **Variables** - Capture data from the conversation for branching and follow-up * **Actions** - Run mid-call integrations (lookups, webhooks, schedulers) so the agent can do real work * **Settings** - Tune voice, language, presence/endpointing, knowledge, and post-call behavior * **Testing (Test Agent & Call Me)** - Validate logic via text and polish the live voice experience with real calls ## Builder workflow (high level) 1. Sketch the flow with Nodes and their types (Start -> Speak -> Transfer/End). 2. Define navigation using Outcomes (pick prompt-based or rule-based per node). 3. Capture facts with Variables (extracted before outcomes). 4. Add mid-call work with Actions (lookups, booking, CRM updates) and route on results. 5. Tune Settings (voice, language, presence, voicemail handling, advanced prompt). 6. Test with Test Agent (text) -> Call Me (live call), then iterate. ## What to use when * **Fixed, must-say lines** -> Use Speak > Message and enable *Repeat verbatim*. * **Composed responses from context/data** -> Use Speak > Prompt. * **Open-ended interpretation** -> Choose prompt-based outcomes. * **Compliance or precision** -> Choose rule-based outcomes. * **Need external data or side effects** -> Add Actions. * **Branching on captured data** -> Combine Variables with rule checks. * **Final polish** -> Adjust Settings and run Call Me. ## Build your first agent (10-minute quick start) 1. Create an agent and set Voice/Language under Settings. 2. Add a Start node with a short opener and any required consent. 3. Add a Speak -> Prompt for qualification, and define three to four Outcomes (for example Book now, Call back, Not interested, Clarify). 4. Add Variables (for example email, budget) with clear extraction instructions. 5. Add an Action (CRM lookup or scheduler) and use rule-based outcomes to branch on results. 6. Use Test Agent to verify paths; then Call Me for a real call and tune presence/latency. 7. Add Transfer and End nodes to finish gracefully. ## Troubleshooting **Agent not responding as expected** * Test with [Test Agent](/agents/testing) first to debug conversation flow * Check that outcomes are configured (prompt-based or rule-based) * Verify variables are extracting data correctly * Review [Settings](/agents/settings) for voice and language configuration **Conversation getting stuck at a node** * Ensure all nodes have outcomes defined (no dead ends) * Add Else/Default outcome in rule-based routing * Check that prompt outcomes have at least 2-3 options * Use [Testing](/agents/testing) to trace execution path **Actions not executing** * Verify integration is connected in [Settings](/agents/settings) * Check action configuration has all required fields * Test integration separately in [Automations](/automations/getting-started) * Review action execution order (actions → variables → outcomes) **Voice quality or timing issues** * Adjust [presence settings](/agents/settings#presence-tab) * Try different voices from the [Voice Selector](/agents/voices) * Test with [Call Me](/agents/testing#call-me-real-call) to hear actual performance * Review network latency and server region settings **Common Mistake**: Building complex flows without testing each node. Always use [Test Agent](/agents/testing) to validate conversation logic before adding more nodes. This catches issues early when they're easy to fix. ## Best Practices * **Actions execute before outcomes** in a node. Order: actions → variables → outcomes. On nodes with actions, outcomes evaluate immediately after the action completes — before the caller speaks again — so use rule-based (not prompt-based) outcomes on action nodes. * **Prompt outcomes** are great for open conversational turns. Use **rule outcomes** for form validation or compliance checks. * **Test with Test Agent** (text) first to refine logic cheaply, then **Call Me** (voice) to polish live sound. * **[Genius](/genius/getting-started) stores information**. Agent instructions or custom prompts shape behavior. * **Start simple**: Build a basic flow, test it, then add complexity incrementally. ## See also * [Nodes](/agents/nodes) - build blocks and their types * [Outcomes](/agents/outcomes) - route the conversation * [Variables](/agents/variables) - capture and reuse data * [Actions](/agents/actions) - run integrations and logic mid-call * [Settings](/agents/settings) - voice, language, presence, advanced customization * [Testing](/agents/testing) - validate and refine your agent * [Genius](/genius/getting-started) - adding knowledge to agents * [Glossary: Voice Agent](/resources/glossary#voice-agent) - understanding voice AI, Call Me, and troubleshooting # Agent settings Source: https://docs.thoughtly.com/agents/settings Tune voice selection, response behavior, transfer rules, and post-call workflows for each Thoughtly agent from a single configuration panel. Fine-tune stability, voice/LLM behavior, and post-call workflows for each agent. Open any agent in the Agent Builder. The builder has three tabs: **Create** (the visual flow editor), **Deploy** (deployment configuration), and **Responses** (redirects to [History](/platform/history) filtered for this agent). Settings are available in the sidebar panel within the Create tab. ## Main settings Main agent settings panel * **Agent name** - Internal label shown to you and your team. * **Conversation type** - Lightly optimizes tone and behavior for your use case. *General* works for most flows. Choose a specific type if you have a narrow scenario (qualification, support, collections, etc.). * **Voice** - Click the Voice field to open the inline **Voice Selector** panel with **Saved** and **Explore** tabs. Browse, preview, and assign voices without leaving the builder. See [Voices](/agents/voices) for full details. * **Language** - Primary speaking language for the agent (for example English or Ukrainian). Set this explicitly if not English and align with your callers' locale. ## Genius tab Genius settings tab * **Attach Genius database** - Connect one of your existing Genius knowledge bases to enable retrieval-augmented answers. * **When to use** - Product FAQs, policy answers, common objections. * **Tips** - Keep entries concise, current, and free of internal jargon. This tab is for **assigning** an existing knowledge base to your agent. To **create** a new Genius database, go to [Tools → Genius](/genius/getting-started). ## Presence tab Presence settings panel Fine-tune how the agent listens and decides when a caller is finished speaking. * **Sensitivity threshold to caller** - Controls how easily the agent treats audio as speech. * Higher value: ignores more background noise, reduces false starts; may miss very quiet voices. * Lower value: captures softer voices; may pick up room noise. * **Recommendation:** start mid-range; increase in noisy environments. * **Silence timeout** - How long to wait after silence before re-engaging (for example "Are you still there?"). Minimum value is 4000ms (4 seconds) to prevent premature re-engagement prompts. * **Silence retries** - Number of re-engagement attempts before ending the call. * **Recommendation:** 1-2 for sales, 0-1 for support/IVR flows. * **Utterance end / endpointing** - Time window that decides when a sentence is considered finished. Larger values give callers more time but add latency; ## Post-call **Deprecation Notice**: Post-call settings are being phased out in favor of [Automations](/automations/getting-started). We recommend using the **On Call Completed** trigger in Automations for all post-call workflows. This provides more flexibility, better error handling, and integration with your full automation stack. Legacy post-call settings allow basic automation after each call ends. These run automatically when the call terminates, regardless of outcome. ### Available Options * **Email notifications** - Automatically send a summary email to all team members after each call completes. The email includes: * Call duration and outcome * Transcript of the conversation * Timestamp and caller information **Use case**: Quick notifications to sales teams or support managers without building a full automation. * **Disposition** - Automatically tag calls based on the transcript content and call outcome. The system analyzes the conversation and applies predefined labels like "Qualified lead," "No answer," "Left voicemail," or "Request callback." **Use case**: Basic call categorization for reporting and filtering in your call history. ### Migration Recommendation For more powerful post-call workflows, use [Automations](/automations/getting-started) with the **On Call Completed** trigger. This gives you access to: * Conditional logic based on call outcomes and variables * CRM updates and data syncing * Multi-step workflows with error handling * Integration with webhooks and third-party services * Advanced notification routing * Flexible trigger scope (one agent, multiple agents, or All Agents) ## Voicemail Allow the agent to leave a message when reaching voicemail. * **Enable voicemail** - When detected, the agent plays your voicemail message and ends the call. * **Best practices:** keep it under 20-25 seconds, include a call-back request and number/URL, and avoid sensitive information. ## Advanced settings * **Advanced prompt** - Overarching instruction the agent considers before anything else. Use it to define persona, tone, and high-level guardrails. Do not put navigation logic here; keep routing in Speak nodes and Outcomes. **Template** ``` You are a helpful, concise sales assistant. Be friendly and confident. Prefer short sentences. If the caller expresses confusion, summarize and ask one clarifying question. Avoid medical or legal advice. ``` **Tips** * Keep it short (3-6 lines). * Avoid duplicating instructions already present in node prompts. * Revisit after a few test calls to tune tone, not logic. ## Setup checklist 1. Name the agent and set Conversation type. 2. Choose Voice, Voice speed, and Language. 3. Attach a Genius database if needed. 4. Tune Presence (sensitivity, silence timeout/retries, endpointing). 5. Configure Post-call notifications and Disposition (or rely on Automations). 6. Enable Voicemail and add a clear message. 7. Add an Advanced prompt for persona; keep routing logic in nodes and outcomes. ## See also * [Voices](/agents/voices) - browse, preview, and assign voices. * [Speak nodes](/agents/nodes#speak-node) - author messages and prompts. * [Outcomes](/agents/outcomes) - routing after each turn. * [Automations overview](/automations/getting-started) - post-call workflows and reporting. ## Variables in advanced prompts Advanced prompts can reference variables that are filled at runtime. This lets you adapt agent behavior based on contact attributes, automation payloads, CRM fields, or channel context. Example: ```text theme={null} The contact's lead source is {{ contact.lead_source }}. If the source is "referral", thank them for being referred before asking qualification questions. ``` Always test variable-backed prompts with realistic sample data before publishing. # Test voice agents before launch Source: https://docs.thoughtly.com/agents/testing Validate conversation logic, voice quality, and integrations with Thoughtly's in-app test caller and simulated runs before deploying an agent to production. Testing entry point in the Agent Builder Validate your flows before going live. These tools save time, catch logic gaps, and ensure the voice experience matches your brand. ## Test Agent (text chat) Test Agent text chat panel **What it does:** Lets you talk to your agent in text. Ideal for fast debugging while building. **Why it is useful** * Instant feedback - no dialing required. * Validate [Outcomes](/agents/outcomes) logic, [Variables](/agents/variables) extraction, and [Actions](/agents/actions) outputs. * Reproduce edge cases quickly by copying and pasting caller messages. **How to use** 1. Click **Test Agent**. 2. Send a few representative messages (greeting, objections, qualification answers). 3. Watch for: * Outcome path taken * Node step numbers in the conversation flow * Variables extracted or updated * Action results and flags 4. Adjust Speak nodes, outcomes, or variables as needed and retest. **Pro tips** * Keep a list of 10-15 common caller phrases per branch and run them after each edit. * Use the self-loop pattern to test Q\&A depth (see [Outcomes -> Loops](/agents/outcomes#loops-special-use-case)). * If a Prompt feels wordy, shorten it and retest - clarity beats cleverness. **Limitations** Text chat does not reveal TTS quality, barge-in timing, or background-noise behavior. Use **Call Me** to test the real call experience. ## Call Me (real call) **What it does:** Places an actual phone call to you from the agent. Perfect for final checks before talking to customers. **What to listen for** * **Voice & style:** Does the selected voice match your brand? Any mispronunciations? Adjust voice/language under [Settings](/agents/settings). * **Barge-in/interruptions:** Are critical lines protected by *Uninterrupted message*? * **Endpointing/latency:** Is the agent cutting callers off or waiting too long? Tune sensitivity, utterance end, and silence timeout/retries in Settings -> Presence. * **Transfer behavior:** Does the [Transfer node](/agents/nodes#transfer-node) hand off cleanly and play the pre-transfer message? * **Action timing:** Do mid-call actions feel smooth? Add a short "One moment..." line if needed. **How to use** 1. Click **Call Me** and confirm your phone number. 2. Take the call and run through your top 5-10 scenarios (success, objections, no-answer, transfer). 3. After the call, review the response log for more information about the call. Node step numbers help you identify exactly where the conversation went during replay. Call review log **Checklist for a pass** * Opener is crisp; consent or disclaimers are verbatim where needed. * Numbers are easy to understand (enable *Read numbers phonetically* for IDs). * Interruptions behave as intended (on for long instructions; off for natural conversation). * Transfers work; voicemails leave the right message. * Post-call notifications and dispositions land where expected (Settings -> Post-call). **Troubleshooting** * Agent talks over you -> lower sensitivity or shorten utterance end (Settings -> Presence). * Agent waits too long -> reduce utterance end or silence timeout. * Wrong path chosen -> check outcome labels for overlap (prompt-based) or rule order (rule-based). * Variables empty or incorrect -> switch source to *Current speak node* for precise asks; tighten extraction instructions. * Mid-call action confusion -> ensure rule-based outcomes check action flags. ## Workflow recommendation 1. Build the flow skeleton with Speak nodes and Outcomes. 2. Validate logic and extractions with Test Agent (text). 3. Add Actions and retest text. 4. Tune Settings (Presence, Voice/Language). 5. Use Call Me for live feel and final polish. ## See also * [Speak nodes](/agents/nodes#speak-node) - author prompts and messages. * [Outcomes](/agents/outcomes) - routing after each turn. * [Variables](/agents/variables) - capture and reuse information. * [Actions](/agents/actions) - mid-call integrations and branching. * [Settings](/agents/settings) - Presence, Voice, Language tuning. * [Voices](/agents/voices) - browse, preview, and assign voices. ## Testing with sample metadata Test Agent can use sample metadata so you can verify how an agent behaves with realistic caller or workflow context before placing a real call. Examples of useful test metadata: ```json theme={null} { "first_name": "Jordan", "lead_source": "website_form", "appointment_type": "consultation", "priority": "high" } ``` Use sample metadata to test personalization, variables, conditional routing, and prompts that depend on CRM or automation data. ## Test chat sessions Text-based test sessions are isolated from live calls. Use them to quickly inspect prompts, branching, and variable usage. For voice quality, interruption behavior, pronunciation, and transfer timing, place a real test call before going live. # Voice agent tips and tricks Source: https://docs.thoughtly.com/agents/tips-and-tricks Practical patterns and best practices for building reliable, natural-sounding Thoughtly voice agents — covering prompts, actions, voices, and edge cases. ## Introduction Building an effective Voice Agent requires more than just adding nodes and connecting them. It demands clarity, logical flow, and adherence to structured guidelines. Thoughtly’s no-code Agent Builder simplifies the process, but following best practices will help ensure reliability, scalability, and ease of maintenance. ## General Best Practices Clear instructions are critical in each node. If a conversation flow is confusing to a human, it will be confusing to AI. Remember, AI does not think smarter than humans—it follows patterns. Avoid spelling errors to prevent misinterpretation, and ensure all text is structured logically. When crafting prompt instructions, do not use special characters such as `*`, `^`, or `$`. These can interfere with parsing and processing, leading to unintended errors. Implementing a system guardrail for this is highly recommended. ### Rules for Building an Agent When you build an agent, you must follow these rules: * No special characters allowed in each node's message/instructions. * No special characters allowed in outcomes, but `-` and `/` are okay. * Outcomes need a minimum of 12 characters. * Node messages can be up to 2000 characters. * No nodes can be connected to themselves or the one directly above them. ## Structuring Nodes Effectively A well-structured Voice Agent depends on clear node organization. Ensuring logical flow between nodes prevents confusion and helps AI handle conversations smoothly. Additionally, avoid unnecessary complexity in node construction: * The start node’s outcome should avoid simulating voicemail detection, as it is unreliable. * If an outcome is labeled "caller has questions" and leads to another node, do not assume the question has already been answered. The next node’s purpose is to provide an explicit answer. * Avoid phrases like "ask me anything." Instead, be specific about the topics the agent can answer to prevent hallucination or unexpected behavior. * Remove all spelling errors. Poorly structured outcomes can be misinterpreted, leading to incorrect logic paths. Additionally, review the actions used in nodes. If an action only references `{{system.contact.phone_number}}`, there may be no need to extract it again from conversation history. Eliminate redundant actions where possible to streamline performance. ### Start Node Your Start Node is the gateway to the conversation. It should be simple, clear, and direct. Avoid attempting to simulate voicemail detection, as it is unreliable. Instead, focus on setting the stage for a structured conversation. ### End Nodes A well-structured conversation needs a clear exit. Multiple end nodes are allowed, but each must include a distinct closing message to ensure a smooth call conclusion. This prevents dead-end interactions and leaves a positive impression on callers. End nodes must use static, verbatim text and cannot reference dynamic variables. This rule ensures consistency and predictability, eliminating potential errors. Node messages can be up to 2000 characters. ### Transfer Nodes Multiple transfer nodes can be used to direct calls efficiently. For phone transfers, use clear messages to guide the caller. For agent transfers, specify the agent’s name and purpose clearly. When using multiple transfer nodes, ensure that each has distinct names or messages to avoid confusion. Like end nodes, transfer nodes must also be static and cannot reference dynamic variables. Implementing this as a system guardrail will prevent potential errors in call routing. Additionally, transfer nodes must have a minimum of 80 characters. ## Optimizing Speak Nodes Speak nodes should strictly contain speech instructions—nothing else. Do not include navigation rules or conditional logic within these nodes. The AI should focus solely on delivering the intended speech. Avoid vague prompts such as “ask me anything.” Instead, anticipate the caller’s possible questions and define clear, specific outcomes to guide the conversation effectively. ## Managing Actions and Variables Variables play a crucial role in customizing responses, but they must be used properly. Ensure that the variable picker includes the node ID for better organization and tracking. Bracketed variables (e.g., `[variable]`) should be used only within speech instructions. They represent dynamic information the agent may reference based on conversation history. Be cautious with replacements in additional rules to maintain consistency and avoid errors. ## Navigating Outcomes Each node must lead to a distinct outcome. Avoid creating loops where a node directly links back to its parent. However, looping back to ancestor nodes is permitted when necessary for logical flow. Ensure that within a given conversation branch, each node has unique instructions all the way up to the start node. If an outcome is meant to address caller questions, do not assume the question has been answered in previous nodes—make sure the next node provides a direct answer. Additionally, outcomes need a minimum of 12 characters. ## Guidelines for Advanced Rules Advanced rules should be used sparingly and only when absolutely necessary. Never include navigation instructions in advanced rules. Statements like "do not move forward unless..." should be avoided. Instead, structure your conversation flow using outcomes and well-defined nodes. Additionally, do not place questions inside advanced rules. Instead, ensure questions are handled within the agent’s node structure for better clarity and response accuracy. Use advanced rules only when absolutely necessary. They should never contain questions or navigation instructions. Instead of relying on complex logic within rules, structure your conversation flow in a way that naturally guides the user through different paths. ## Best Practices for Genius Data Integration Genius data sources should always follow a strict Question & Answer (Q\&A) format. Avoid including unnecessary details—concise, well-structured data reduces hallucinations and improves response accuracy. Review each Genius data source regularly and ensure it aligns with the Q\&A format. The current format in some agents may be confusing the model, leading to incorrect or irrelevant responses. Remove any unnecessary information to enhance accuracy. Exercise caution with scheduling data and time-sensitive information. Since AI does not have real-time context awareness, incorrect or outdated information can lead to confusion. Regularly review and update Genius data sources to maintain reliability. ## Ensuring Effective Data Extraction Data extraction nodes must be set up correctly to function as intended. Every data extraction action should have a clearly defined field for extraction. Before deployment, test extraction actions in the output tab using a sample response. If the test returns no output, it indicates an issue that must be fixed before production use. Ensure that the field being extracted is valid. If an agent is attempting to extract a field that does not exist, such as "Phone Optimization," the action will fail. Test the extraction in the output tab before proceeding to avoid unnecessary errors. ## Final Thoughts Following these best practices will help you build a robust and effective Thoughtly Voice Agent. By structuring nodes properly, defining distinct outcomes, and ensuring clear speech instructions, you can create a seamless and professional AI-powered voice experience. Keep refining and testing your agent to achieve optimal performance and user satisfaction. # Troubleshoot Thoughtly voice agents Source: https://docs.thoughtly.com/agents/troubleshooting Diagnose and resolve common voice agent issues including audio quality, transfers, action failures, prompt drift, and unexpected hang-ups in Thoughtly. ## Common Issues ### Agent Not Responding as Expected If your agent isn't responding correctly: * Review your agent's configuration in [Settings](/agents/settings) * Check [Outcomes](/agents/outcomes) and [Variables](/agents/variables) setup * Verify node connections in the agent builder * Test with simple conversations first using [Test Agent](/agents/testing) ### Call Quality Issues For call quality problems: * Check internet connection stability * Verify phone number configuration in [Phone Numbers](/phone-number/configuration) * Review the [Settings](/agents/settings) including voice and presence tuning * Test with different voice options from the [Voice Selector](/agents/voices) ### Agent Not Following Node Flow If your agent isn't following the intended conversation flow: * Verify all nodes are properly connected * Check outcome conditions and logic * Review the [Nodes](/agents/nodes) documentation * Test each branch of the conversation separately ### Variable Issues For variable-related problems: * Ensure variables are properly defined * Check variable scope and availability * Review the [Variables](/agents/variables) guide * Verify data is being passed correctly ### Special Characters in Call Transcripts If your agent is pronouncing special characters (asterisks, underscores, brackets, etc.) during calls: The LLM may be generating speech-like markdown that includes special characters. To resolve this, add the following instructions to your agent's **Advanced Prompt** (not individual speak nodes): ``` You are writing text for TTS; special characters like *, _, #, [, ], (, ), etc. must never appear. Never output special characters under any circumstance. If input contains special characters, remove them and rewrite naturally. If you need to refer to a special character, spell out its name (e.g., "asterisk", "underscore"). ``` This ensures the instruction applies to the entire agent and prevents special characters from appearing in the call transcript or being pronounced by the TTS system. For additional assistance, visit our [Support Center](/support/getting-help). # Variables in voice agents Source: https://docs.thoughtly.com/agents/variables Capture caller data into variables and reuse it across nodes for branching, action payloads, dynamic prompts, and post-call follow-up in Thoughtly. **Prerequisites**: Review [Speak Nodes](/agents/nodes#speak-node) and [Outcomes](/agents/outcomes) first. Variables let your agent **capture information from the conversation** for use later: within the same call (branching with [Outcomes](/agents/outcomes), deciding [Actions](/agents/actions)) and after the call (CRM updates, notes, automations). **When they extract:** Immediately after the caller's latest reply and **before** outcome evaluation. That means your outcomes can reference fresh variable values right away. Add variables from the right panel of a [Speak node](/agents/nodes#speak-node). Open the node, scroll to **Variables**, and click **Add variable**. Variables panel in the Agent Builder ## Visual type indicators Variables display with type-specific icons throughout the Agent Builder to help you quickly identify their format: * **Text variables** show a text icon * **Number variables** show a grid icon * **Boolean variables** show a customize icon These icons appear in: * The variable picker dropdown when inserting variables into messages * Variable chips within the message editor * The variables list in speak nodes * Canvas node previews * Outcome rules that reference variables This visual system makes it easier to track variable types at a glance and ensures you're using the correct format in your logic. ## Fields * **Name** - A short, readable identifier you will reference in rules and prompts (for example `budget`, `email`, `callback_time`). * **Source** - Choose **Current speak node** or **Conversation history**. * *Current speak node* extracts only from the caller's most recent turn, ignoring earlier context. Great for precise questions such as "What is your email?" when you only want the latest answer. * *Conversation history* searches the entire conversation for the best value. Useful when the caller may have mentioned it earlier or you want a fallback. * **Extraction instructions** - This is the heart of the variable. Write exactly what to extract and how to transform it. Be explicit about constraints, examples, and edge cases. Variable extraction editor **Template you can copy** ```text theme={null} Goal: Extract the the caller states. If multiple candidates: choose the most recent, high-confidence value. If absent or unclear: return an empty value (no placeholder text). Normalization: . Do not invent values. ``` * **Format** - Enforces the output type so downstream logic stays predictable. Each type displays with a unique icon throughout the Agent Builder for easy identification. * **Text** - Text values (names, emails, addresses). Displays with a text icon. * **Number** - Numeric only (budgets, credit scores). The system requires a valid number. Displays with a grid icon. * **Boolean** - True/false values (consent, qualification). Displays with a customize icon. ## Authoring examples Name: `budget`
Source: Current speak node
Extraction instructions: Extract the maximum home budget the caller states as a plain number in USD, with no commas or text. If a range is given (for example "200 to 250k"), choose the upper bound. If not provided, leave empty.
Format: Number
Use with: Rule outcome `budget >= 250000` -> High-intent path.
Name: `email`
Source: Conversation history
Extraction instructions: Extract the caller's email. Normalize to lowercase and remove spaces. If multiple addresses are present, choose the most recent. If none, leave empty.
Format: Text
Use with: Rule outcome `email` matches `/.+@.+\\..+/` -> Collect address details.
Name: `callback_ok`
Source: Current speak node
Extraction instructions: Determine whether the caller has explicitly agreed to a call-back. Return `true` for clear consent like "Yes, call me later," otherwise return `false`.
Format: Boolean
Use with: If `callback_ok == true` -> trigger [Actions](/agents/actions) to create a follow-up task.
## Re-extraction and overrides * Each time the agent visits a node that defines a variable, it retries extraction and overwrites the previous value if it finds a better one. * You can intentionally redefine variables later to refine accuracy (for example, asking the caller to confirm their email). * Prefer *Current speak node* for confirmations to avoid pulling older mentions from the conversation history. ## System variables Thoughtly provides built-in system variables that you can reference in your agent without defining them explicitly: * **`{{system.interviewResponse.id}}`** - The unique call ID for the current conversation. Use this to reference the specific call in mid-call actions, webhooks, or external systems. **Example use case:** Pass the call ID to a webhook during the call so your external system can track which conversation triggered the action. ```text theme={null} Webhook URL: https://api.example.com/call-events?call_id={{system.interviewResponse.id}} ``` ## Referencing node responses You can reference data captured at specific nodes using the node step number. When a node extracts information or receives a response, you can access it later in the conversation using the format `Node #[step]: Answer` or `Node #[step]: [field_name]`. **Example:** If node step 3 asks for the caller's email and node step 5 performs an API lookup, you can reference the email response as `Node #3: Answer` in your API action configuration or in subsequent speak node prompts. Node step numbers are automatically assigned sequentially (Start = 0, then 1, 2, 3, etc.) and remain consistent throughout the conversation, making it easy to reference earlier responses even as you modify your agent flow. ## AI-Generated Variables Many times, you'll want to create a variable that is generated by an AI model. For example, you might want to create a variable that contains the caller's email address, or keywords that were mentioned based on the call [transcript](/resources/glossary#transcript). ## Validation patterns (pair with Outcomes) Use rule checks to keep data clean: * **Required:** If `email` is empty -> loop back to re-ask (self-loop pattern; see [Outcomes](/agents/outcomes#loops-special-use-case)). * **Ranges:** `credit_score` between 300 and 850; `budget >= 250000`. * **Flags from Actions:** for example `crm_lookup_found == true`. ## Troubleshooting **Variable extracting incorrect data** * Make extraction instructions more specific and concrete * Switch from Conversation history to Current speak node for precision * Add examples of correct format in extraction instructions * Test with [Test Agent](/agents/testing) to verify extraction **Variable always empty** * Verify caller is actually providing the information * Check if variable source is set correctly (current vs history) * Ensure extraction instructions aren't too restrictive * Review [test call recordings](/agents/testing#call-me-real-call) for what was said **Wrong format being extracted** * Confirm Format field matches expected type (Text/Number/Boolean) * Add explicit format requirements to extraction instructions * Use validation rules in [Outcomes](/agents/outcomes) to catch errors **Variables conflicting with actions** * On nodes with actions, the order is: actions run → variables update from action results → outcomes evaluate (see [Actions](/agents/actions) for execution order) * Variables do update from action results on the same node, so you can branch on action output without a separate node * Use a separate node only if you need the caller to speak again before the next action or outcome **Common Mistake**: Using vague extraction instructions like "Get their contact info." Be specific: "Extract phone number in format +1-555-555-5555 from caller's response. If not provided, leave empty." ## Best practices * **Order of operations:** Variables extract before outcomes, so branching logic always sees the latest values. * **Be explicit:** The more concrete your instructions, the higher the accuracy. Avoid vague wording. * **Handle empty values:** Plan what happens if the variable is missing (default branch, re-ask loop). * **Name consistently:** Use lowercase snake\_case (for example `credit_score`, `callback_time`) so rules stay readable. * **PII caution:** Only capture the [personally identifiable information](/resources/glossary#pii) you actually need. ## See also * [Outcomes](/agents/outcomes) - branch using the variables you extract * [Speak nodes](/agents/nodes#speak-node) - where variables live and update * [Actions](/agents/actions) - set or update variables via lookups and APIs * [Transfer node](/agents/nodes#transfer-node) - escalate when validation fails repeatedly * [Testing](/agents/testing) - validate variable extraction with Test Agent * [Glossary: PII](/resources/glossary#pii) - handling sensitive data responsibly ## Channel type variable When building omnichannel workflows, use the channel type to adjust agent behavior by medium. For example, an agent can write shorter copy for SMS, longer copy for email, and spoken phrasing for voice. Example use cases: * Route email conversations to a different branch than voice calls. * Keep SMS replies under a target length. * Avoid voice-specific phrases in email or WhatsApp. * Track outcomes by channel in analytics. ## Variables in more fields Variables can now be used in more builder fields, including prompts, extraction instructions, number fields, date fields, and selected integration inputs where supported. Use the data picker when available to avoid typos. # Vibes AI assistant Source: https://docs.thoughtly.com/agents/vibes-assistant Build and refine Thoughtly voice agents conversationally with Vibes, an AI assistant that drafts prompts, nodes, and outcomes from plain-language instructions. Vibes helps you create and edit Thoughtly agents through natural conversation. Instead of starting with a blank canvas, describe the workflow you want and Vibes can draft nodes, outcomes, prompts, and actions for you. Use Vibes as a guided builder, not a replacement for review. After Vibes creates or edits an agent, inspect the flow, required fields, integrations, variables, and compliance copy before publishing. Thoughtly dashboard with Vibes prompt box ## What Vibes can help with Vibes can assist with: * Building a new agent from a plain-language description * Updating an existing flow * Adding or editing nodes and outcomes * Drafting prompts and messages * Configuring agent settings * Explaining how a workflow is structured * Iterating on a flow after testing ## When Vibes asks questions If your request is too broad, Vibes may ask clarifying questions before building. This avoids creating a generic agent that misses important business logic. Vibes may ask about: 1. **Business type** — the industry or use case 2. **Agent objective** — what the agent should accomplish 3. **Information to collect** — name, email, budget, appointment type, objections, or other fields 4. **Integrations** — CRM, calendar, SMS, webhook, email, or other systems 5. **Routing and success criteria** — when to transfer, end, follow up, or mark the conversation successful ## Good prompts Good Vibes prompts are specific about the desired outcome. ```text theme={null} Build a lead qualification agent for a home-services company. It should greet inbound callers, ask what service they need, collect address and timing, qualify urgency, and transfer emergencies to our dispatch line. For non-emergencies, create a callback task and send an SMS confirmation. ``` ```text theme={null} Create an SMS follow-up agent for missed calls. If the contact replies, ask whether they still need help, collect the best callback time, and update the contact with the requested service. ``` ```text theme={null} Update this agent so that when the caller asks for pricing, it gives a short answer, collects their email, and sends a follow-up through the Send Email action. ``` ## Vague prompts Vague prompts usually need follow-up before Vibes can build well. ```text theme={null} Build me a scheduling agent. ``` Better: ```text theme={null} Build a scheduling agent for a dental office. It should ask whether the patient is new or returning, collect preferred days, check Calendly availability, book the selected slot, and send an SMS confirmation. ``` ## Review checklist Before publishing a Vibes-generated flow: * Confirm the agent goal and success criteria are correct. * Read every message and prompt in the expected channel context. * Check that variables reference the right fields. * Confirm required integrations are connected. * Verify transfer numbers, scheduling links, and webhook URLs. * Test with realistic metadata in [Test Agent](/agents/testing). * Make sure compliance language, opt-out handling, and suppression rules fit your workflow. Vibes can accelerate setup, but generated flows should still be reviewed and tested before production use. ## Troubleshooting ### Vibes built the wrong thing Ask Vibes to modify the specific part that is wrong, or edit the flow manually. For best results, name the node, action, or outcome you want changed. ### Vibes skipped questions If you want a more guided setup, start with a shorter request and answer the clarification questions. If you already provided enough details, Vibes may proceed directly to building. ### You navigated away during setup If Vibes was asking questions and you left the Agent Builder, return to the same agent. Your pending question card should reappear. If it does not, refresh the page. # Bring Your Own Key (BYOK) for voices Source: https://docs.thoughtly.com/agents/voice-byok Connect your own ElevenLabs, Cartesia, or other voice provider API keys to Thoughtly to use your personal voices, usage limits, and provider pricing. ## What is BYOK? **Bring Your Own Key (BYOK)** lets you connect your own voice provider API key to Thoughtly. Instead of using shared platform credentials, your agents use your provider account directly. This gives you: Rate limits and quotas come from your provider plan, so you are never constrained by shared platform limits. Volume discounts or custom pricing you have arranged with your provider apply automatically. [Clone custom voices](/agents/voice-cloning) stored directly in your provider account for full ownership and portability. Your private, cloned, and generated voices appear alongside the full public catalog. ## ElevenLabs ### Connect your key A paid ElevenLabs plan (**Starter** or above) is required. Free ElevenLabs API keys cannot be connected because the validation step rejects them. You can find your API key in your [ElevenLabs dashboard](https://elevenlabs.io) under **Profile + API key**. Go to **[Settings > Integrations](https://app.thoughtly.com/integrations)** in the Thoughtly dashboard. Look for the **ElevenLabs** card. Click **Connect** on the ElevenLabs card and paste your API key. Thoughtly validates the key against your ElevenLabs account before proceeding. Once validated, Thoughtly automatically imports your **cloned** and **generated** voices from ElevenLabs into your workspace voice library. These voices appear in the **Saved** tab tagged with **Your ElevenLabs**. After connecting, the ElevenLabs card on the Integrations page shows **Connected**. ### Review your subscription Once connected, you can view your ElevenLabs subscription details directly in Thoughtly. The subscription screen shows: * **Plan tier** and billing period * **Character usage**: how many characters you have used out of your monthly quota, and when it resets * **Voice slots**: how many custom voice slots you have used and how many are available * **Features**: which capabilities your plan includes, such as Instant Voice Cloning and Professional Voice Cloning Use this screen to monitor your usage and confirm your plan supports the features you need. ### What changes after connecting Once your ElevenLabs key is active: * A **Your ElevenLabs** badge appears in the Voice Selector header, confirming BYOK is active. * The **Saved** tab shows only voices linked to your ElevenLabs account. Built-in default voices (like Tessa, James, Lisa) are hidden. * The **Explore** tab shows the full voice catalog. When you save or assign a voice, it is linked to your credentials automatically. * [Voice cloning](/agents/voice-cloning) creates clones in your ElevenLabs account rather than using Thoughtly's shared account. * **Cartesia voices** remain available regardless of BYOK status. If the Saved tab is empty after connecting, your ElevenLabs account may not have any cloned or generated voices yet. Use the **Explore** tab to save voices, or [clone a new voice](/agents/voice-cloning). ### Concurrency Your ElevenLabs plan determines how many simultaneous voice requests your agents can make. If your agents exceed this limit, calls may experience delays or fall back to a default voice. | Plan | Concurrent requests | | -------- | ------------------- | | Starter | 3 | | Creator | 5 | | Pro | 10 | | Scale | 15 | | Business | 15 | Concurrency is managed entirely by ElevenLabs based on your plan. If you need higher limits, upgrade your ElevenLabs plan or contact ElevenLabs about enterprise options. ### Managing your key Your ElevenLabs API key is managed on the **[Integrations](https://app.thoughtly.com/integrations)** page. **Rotating your key**: disconnect the current key and reconnect with the new one. Thoughtly re-imports your voices automatically on reconnect. **Disconnecting**: go to **Settings > Integrations** and remove the ElevenLabs connection. Disconnecting removes all BYOK-linked voices from your workspace library. Agents that were using those voices fall back to the default voice. Cartesia voices are not affected. A small number of enterprise workspaces operate without BYOK and instead use Thoughtly-managed voice credentials. If your Saved tab shows built-in default voices rather than your own ElevenLabs library, contact your account manager for setup assistance. ## Workspace-Level Library Saved voices belong to the **workspace**, not individual users: * All team members can access saved voices across their agents * Voice selections persist across sessions * No per-user sharing limitations ## Premium Voices Some voices consume more [Credits](/platform/billing) per minute. These are badged with a multiplier like **2x cost** or **3x cost** in both the Saved and Explore tabs. Use premium voices for high-value interactions and standard voices for volume. ## Troubleshooting * BYOK is rolled out gradually. If you don't see the card for your provider, contact your account manager to enable it for your workspace. * Verify the key is copied correctly with no extra spaces. * Confirm the key is active in your provider's dashboard. * Check that your subscription with the provider has not expired. * Only **cloned** and **generated** voices are imported automatically. Standard library voices must be saved manually from the **Explore** tab. * If you recently created voices in your provider account, disconnect and reconnect to re-import. * **Did you save it?** In the Explore tab, click the **Bookmark** icon or click the voice row to save + assign. Just pressing Play does not save. * **Check your key**: Your Saved tab shows voices linked to your [BYOK](#what-is-byok) credentials. Confirm your API key is active on the **Integrations** page. * **Refresh**: Close and reopen the Voice Selector panel, or refresh the Agent Builder page. * **Vendor removal**: The voice may have been removed by Cartesia or ElevenLabs. * Previews use sample text; real calls use your agent prompts, which may sound different. * Tune [Presence settings](/agents/settings#presence-tab) (sensitivity, endpointing) to optimize real-call behavior. * Always test with [Call Me](/agents/testing#call-me-real-call) before deploying. * Check your internet connection. The voice catalog may be temporarily unreachable. * Try refreshing the Agent Builder page. * If the problem persists, check the [Platform Status](https://status.thoughtly.com) page. * Add phonetic spellings to your agent prompts (e.g. "Thoughtly" → "Thought-lee"). * Create pronunciation entries in your [Genius](/genius/getting-started) knowledge base. * Consider [Voice Cloning](/agents/voice-cloning) for specialized terminology. * Rewrite prompts conversationally. Use contractions, short sentences, and natural phrasing. * Add punctuation for pacing: commas for short pauses, periods for longer breaks. * Try a different voice from the Explore tab. * Confirm the agent's **Language** setting matches the voice's language. * Use the **Language** filter chip in the Explore tab to find voices in the correct locale. * See [Voice Optimization](/agents/voice-optimization#choosing-the-right-voice) for accent-matching strategies. ### Still stuck? If none of the above resolves your issue: 1. Note your **Team ID** (found in workspace settings) 2. Describe the exact steps you took and what you expected to happen 3. [Contact support](/support/getting-help) with this information ## Test your ElevenLabs connection After adding an ElevenLabs API key, use **Test Connection** to confirm that Thoughtly can access your account and voices. If the test fails, verify that the key is active and has access to the voices you expect to use. ## Legacy voice behavior Some older workspaces may have legacy voice configurations. If a legacy voice no longer appears in the selector, choose an available Cartesia voice or connect your own ElevenLabs key to use custom ElevenLabs voices. # Voice cloning for agents Source: https://docs.thoughtly.com/agents/voice-cloning Create custom voice clones for Thoughtly agents by recording or uploading audio samples directly inside the Agent Builder, with quality and consent tips. Create custom voice clones to give your agents a unique, brand-specific sound that isn't available in the public voice library. The **Clone Voice** modal is accessible directly from the **Saved** tab in the Agent Builder's Voice Selector. ## Requirements | Requirement | Detail | | ----------------------- | ------------------------------------------------------------------------------------------ | | **Recording length** | Up to 20 seconds (stops automatically at 20 s). Record the full duration for best results. | | **Upload length** | No length limit for uploads. Longer samples can improve quality. | | **Input method** | Browser microphone recording **or** audio file upload | | **Supported formats** | Any browser-compatible audio format (WAV, MP3, etc.) | | **Browser permissions** | Microphone access must be granted for recording | If your workspace uses [BYOK](/agents/voice-byok), cloned voices are created in your own provider account and tagged accordingly in the Saved tab (for example, **Your ElevenLabs**). This gives you full ownership and portability of your cloned voices. ## Cloning Step-by-Step Open your agent → click the **Voice** field → in the **Saved** tab, click the **Clone a voice** banner at the top. The Clone Voice modal opens. The Clone banner is hidden while the Saved tab search filter is active. Clear the filter text to see it again. Enter a descriptive **Voice Name** (e.g. "Sarah, Sales US"). This is how the voice appears in your Saved tab. Select the **Language** and **Gender** for the voice. These metadata fields help you filter and organize voices later. Supported cloning languages: English, Spanish, French, German, Portuguese, Italian, Japanese, Korean, Chinese, Hindi, Dutch, Polish, Russian, Swedish, and Turkish. Gender options: **Male**, **Female**, or **Not specified** (default). **Option A, Record**: Click **Record Voice**. Speak naturally while the progress bar fills. Recording stops automatically at **20 seconds**, or click **Stop Recording** to end early. For best results, record the full 20 seconds. **Option B, Upload**: Click **Upload Audio File** beneath the record button and select an audio file from your device. After recording or uploading, an audio player lets you review the sample. Click **Discard Recording** to start over. Click **Clone**. Processing typically takes 30 to 60 seconds. When complete, the modal switches to a results screen showing the voice name and a preview player. Click **Done** to close the modal. Your new voice now appears in the **Saved** tab, ready to be assigned to any agent. Clone Voice modal with name field, language/gender selectors, and record button ## Recording Best Practices * **Quiet environment**: minimize background noise and echo * **Quality microphone**: external mics give better results than built-in laptop mics * **Consistent volume**: maintain a steady speaking level * **Clear articulation**: speak naturally but avoid mumbling * **Conversational style**: record in the tone you want agents to use * **Complete sentences**: include full thoughts with natural pauses * **Varied intonation**: demonstrate slight pitch and pacing variation * **Full 20 seconds**: record the maximum duration for best results. For uploads, longer samples generally produce better clones. * Grant microphone permissions when prompted by the browser * Use Chrome or Edge for best recording compatibility * Maintain a stable internet connection during upload and processing ## Managing Cloned Voices After cloning, the voice is immediately available in the **Saved** tab of the Voice Selector alongside other saved voices and built-in defaults. You can: * **Preview** it like any other voice (Play / Pause) * **Assign** it to agents by clicking the voice row * **Remove** it with the Bookmark icon or delete it from the results screen ### Workspace-Level Access Cloned voices are scoped to your **workspace**: * **Private**: not shared with other Thoughtly workspaces * **Team-wide**: all workspace members can use cloned voices * **Persistent**: voices remain until manually deleted ### Multi-Agent Usage A single cloned voice can be assigned to **unlimited agents** simultaneously with no call-volume restrictions. ## Removing or Deleting a Cloned Voice There are two ways to remove a cloned voice: * **Delete** (permanent): On the results screen immediately after cloning, click **Delete**. This permanently destroys the voice. * **Unsave** (remove from library): In the Saved tab, click the **filled Bookmark** icon on the cloned voice row. This removes it from your workspace's saved library. Deleting or unsaving a cloned voice that is currently assigned to agents will cause those agents to fall back to the default voice. ## Legal and Ethical Considerations **Consent is required.** Only clone voices from individuals who have explicitly authorized their voice to be used for AI synthesis in a business context. * **Document consent**: keep written records of voice-use permissions * **Professional use only**: limit usage to appropriate business contexts * **Brand alignment**: ensure the voice represents your brand appropriately ## Data Storage and Privacy * Raw audio is used for clone generation and stored securely within your workspace * Cloned voice models are isolated per workspace. There is no cross-workspace access. * Refer to Thoughtly's data retention policies for storage duration details ## Troubleshooting * Check browser microphone permissions (Settings → Privacy → Microphone) * Verify your microphone works in other apps * Try a different browser (Chrome recommended) * Re-record the **full 20 seconds** of clear, varied speech in a quiet room, or upload a longer audio file * Use an external microphone if possible * If uploading a file, ensure it's not heavily compressed or low-bitrate * Allow up to 2 minutes for complex samples * Check your network connection. The upload may have stalled * Contact [support](/support/getting-help) with your Team ID if processing exceeds 5 minutes * Confirm you reached the **results screen** (voice name + preview player shown) * Close and reopen the Voice Selector panel * Refresh the Agent Builder page ### Still stuck? If none of the above resolves your issue: 1. Note your **Team ID** (found in workspace settings) 2. Describe the exact steps you took and what you expected to happen 3. [Contact support](/support/getting-help) with this information ## See Also * [Agent Voices](/agents/voices): browse, preview, and assign voices * [Agent Settings](/agents/settings): full agent configuration reference * [Platform Billing](/platform/billing): understanding credit usage # Voice optimization for natural speech Source: https://docs.thoughtly.com/agents/voice-optimization Improve agent voice quality in Thoughtly with accents, language selection, speaking-speed controls, and pronunciation overrides for tricky words and names. ## Match Accent to Market Pick a voice accent that matches your caller's region. This improves trust and comprehension. | Market | Recommended accent | | ----------------- | -------------------- | | **North America** | US English | | **Europe** | UK English | | **ANZ** | Australian English | | **Mexico** | Mexican Spanish | | **Spain** | Castilian Spanish | | **Argentina** | Argentine Spanish | | **Brazil** | Brazilian Portuguese | | **Portugal** | European Portuguese | Test with native speakers in your target market before going live. ## Language Each agent has a **Language** dropdown in the conversation settings sidebar. Pick the language, then assign a voice in that same language. Mismatched voice/language pairs cause noticeable pronunciation problems. Thoughtly supports 35 languages. If you need a language that is not listed in the dropdown, [contact support](/support/getting-help). To serve callers in multiple languages, create a separate agent per language with matching voice and [Genius](/genius/getting-started) knowledge base. ## Speed (Cartesia) Cartesia voices have a **Voice Speed** slider in the **Presence** section of the Agent Builder sidebar. The slider runs from 0 (slowest) to 100 (fastest), with 50 as the default. Small adjustments of 10 points are noticeable. The slider is disabled when a non-Cartesia voice is active. ## Volume (Coming Soon) A volume slider for Cartesia voices is in development and will appear alongside the speed control in Presence settings. ## Pronunciation Fixes If your agent mispronounces names, brands, or industry terms: 1. **Phonetic spelling in prompts**: write "Thought-lee" instead of "Thoughtly" 2. **Genius pronunciation guide**: add entries to your [Genius](/genius/getting-started) knowledge base with the correct spoken form 3. **Voice cloning**: [clone a voice](/agents/voice-cloning) that naturally handles your domain vocabulary # Agent voices Source: https://docs.thoughtly.com/agents/voices Browse the Thoughtly voice library, preview samples, and assign a voice to your agent directly inside the Agent Builder across multiple languages and styles. Voice selection in Thoughtly happens **inside the Agent Builder**. When you open an agent and click the **Voice** field in the right-hand sidebar, the Voice Selector panel opens with two tabs: **Saved** (shown by default) and **Explore**. This gives you everything you need to browse, preview, save, and assign voices without leaving the builder. ## Voice Platforms Voices are sourced from two industry-leading providers: Ultra-low-latency voice synthesis with expressive, professional voices. Features real-time generation, speed control, and advanced audio capabilities. Natural-sounding voices with a wide selection of accents, styles, and personalities. A trusted choice for conversational AI. ### Saved Tab Your personal voice library. Voices you have previously saved appear here, **grouped by language**. The active voice's language group is pinned to the top, and the active voice itself is highlighted within it. Most workspaces connect their own voice provider account to access voices. See [Bring Your Own Key (BYOK)](/agents/voice-byok) for details on connecting your API key. A small number of enterprise workspaces use Thoughtly's built-in voice set instead and see 13 default English voices labeled **Built-in**. | Element | What it does | | --------------------- | ---------------------------------------------------------------------------------------------------- | | **Voice row** | Shows avatar, name, platform, gender, and cost multiplier | | **Play / Pause** | Instantly preview the voice audio | | **Bookmark (filled)** | Remove the voice from your Saved library | | **Clone a voice** | Opens the [Clone Voice](/agents/voice-cloning) modal (record or upload) | | **Filter** | Click the search icon in the header to filter saved voices by name, language, accent, or description | ### Explore Tab The **Explore** tab inside the Agent Builder's Voice Selector gives you access to thousands of professional voices from **Cartesia** and **ElevenLabs**. The **Expressive** toggle is enabled by default, prioritizing low-latency, expressive voices. Toggle it off to browse the full catalog across both platforms. You can search, filter, preview, and save, all without leaving the agent you're editing. Explore tab showing filter chips and voice search results grouped by language #### Filter Chips | Filter | Behavior | | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Expressive** | Enabled by default. Prioritizes low-latency, expressive voices optimized for real-time conversations. Toggle off to browse the full catalog across all platforms. | | **Gender** | Select **Male** or **Female** to narrow results. | | **Language** | Choose from 15 languages (with flag icons): English, Spanish, French, German, Portuguese, Italian, Japanese, Korean, Chinese, Hindi, Arabic, Polish, Dutch, Russian, Turkish. | Filters can be combined. For example, enable **Expressive** + **Female** + **Spanish** to find low-latency female voices in Spanish. #### Text Search Click the **search icon** (🔍) in the panel header to open a search bar. Type a voice name or keyword and results update automatically as you type. When no results match, a **Clear filters** link appears. Clicking it resets the Gender filter, Language filter, and search text. The **Expressive** toggle is separate and must be toggled off manually if you want to broaden results further. #### Previewing Voices Every voice row shows a **Play** button on hover. Click it to hear a sample. Click again (or click **Pause**) to stop. Only one preview plays at a time. Starting a new preview automatically stops the previous one. Voice row with Play and Bookmark action buttons visible on hover #### Saving and Assigning a Voice There are two ways to use a voice from Explore: **Click to Save + Assign (Recommended)** Click anywhere on a voice row. Thoughtly will: 1. **Save** the voice to your workspace library (if not already saved) 2. **Assign** it to the current agent 3. **Close** the Voice Selector and return you to the agent sidebar This is the fastest path. One click does everything. **Bookmark for Later** If you want to save a voice **without** assigning it right now, click the **Bookmark** icon on hover. The voice appears in your **Saved** tab for future use across any agent. To remove a bookmarked voice, click the **filled Bookmark** icon to unsave it from your library. Voice availability depends on the vendor and can occasionally change. If a voice you rely on becomes unavailable, [contact our support team](/support/getting-help) and we will help you find a replacement. #### Pagination Results load 50 voices at a time. If more are available, a **Load more voices** button appears at the bottom. Click it to fetch the next page. Loading state is shown while fetching. ## Voice library behavior The voice selector loads voices in pages. If more voices are available, use **Load more voices** to continue browsing. Voices should appear only once even when loading additional pages. ## ElevenLabs and Cartesia availability Workspace voice availability can depend on your plan and whether Bring Your Own Key is enabled. If your workspace uses ElevenLabs BYOK, connect and test your ElevenLabs key before expecting ElevenLabs voices to appear in the selector. # Get agents Source: https://docs.thoughtly.com/api-reference/agent/get-agents get /interview This endpoint retrieves a list of **Agents** (formerly **Interviews**) available in your system. You can filter the list by status, search term, and sorting options. # Search calls Source: https://docs.thoughtly.com/api-reference/agent/search-calls get /interview/{interview_id}/responses Find calls made by an **Agent** (formerly **Interview**). You can filter and search calls based on various criteria. # Call a contact Source: https://docs.thoughtly.com/api-reference/contact/call-a-contact post /contact/call This endpoint allows you to initiate a call with a **Contact** using a specific **Agent**. The **Agent** will handle the conversation during the call. # Create contact Source: https://docs.thoughtly.com/api-reference/contact/create-contact post /contact/create This endpoint allows you to create a new **Contact**. A contact represents a person with whom you can interact via a phone call or other communication. # Delete contact Source: https://docs.thoughtly.com/api-reference/contact/delete-contact delete /contact/{id} This endpoint allows you to delete a **Contact** by ID. Deleting a contact will remove it from the system permanently. # Get contact Source: https://docs.thoughtly.com/api-reference/contact/get-contact get /contact/{id} Retrieve a single **Contact** by their unique ID. Returns the full contact record including name, phone number, email, tags, and any custom attributes associated with the contact. # Get contacts Source: https://docs.thoughtly.com/api-reference/contact/get-contacts get /contact This endpoint retrieves a list of **Contacts**. You can filter contacts by various criteria, such as tags, phone numbers, and more. Use the query parameters to narrow down your results. # Update contact Source: https://docs.thoughtly.com/api-reference/contact/update-contact post /contact/{id}/update_info Update an existing contact's name, phone number, email, tags, or custom attributes by ID using the Thoughtly contact update endpoint. # Get user details Source: https://docs.thoughtly.com/api-reference/user/get-user-details get /user Retrieve the details of the currently authenticated user. This includes information such as user ID, name, and email. # Get currently active webhooks Source: https://docs.thoughtly.com/api-reference/webhooks/get-currently-active-webhooks get /webhooks Retrieve a list of all active webhooks for the authenticated user. This allows you to see which webhook events you are currently subscribed to. # Subscribe to webhook Source: https://docs.thoughtly.com/api-reference/webhooks/subscribe-to-webhook post /webhooks/subscribe This endpoint allows you to subscribe to a specific webhook event (e.g., new call responses or phone transfers). You must provide the event type and a callback URL. # Trigger automation with webhook Source: https://docs.thoughtly.com/api-reference/webhooks/trigger-automation-with-webhook post /webhook/automation/{automation_id} This endpoint triggers an [Automation](/automations/getting-started) with a [Webhook](/automations/triggers#webhook) as the trigger. # Unsubscribe from webhook Source: https://docs.thoughtly.com/api-reference/webhooks/unsubscribe-from-webhook delete /webhooks/unsubscribe This endpoint allows you to unsubscribe from a previously subscribed webhook event. Provide the event type and the callback URL to unsubscribe. # Automation actions and steps Source: https://docs.thoughtly.com/automations/actions Compose Thoughtly automations from steps for branching logic, outbound calls, scheduling, CRM updates, and integrations triggered before or after a call. After you choose a ***Trigger***, **Steps** are where your automation does the work: branching, looping, calling people, writing to CRMs, scheduling, sending webhooks, and more. Open an automation and add a **Step**. ## 1) Step anatomy and data mapping Most steps share these tabs (similar to triggers).
Account / Configure
Output
Next step

Connect the account (if required) and configure step-specific options.

* **Account / Configure** - Connect the account (if required) and set step-specific options. * **Output** - Preview the **result schema** this step produces (or expects). Click **Refresh** after a **Draft** run to update it. * **Next step** - Choose the next node in the flow. **Referencing earlier data** Automation data picker * Click the lightning icon to open the data tree. * Pick the **Trigger** or any previous **Step** as the source, then click fields to insert them. * Click the **+** next to a branch to insert an entire sub-object (for example, the full contact). **Examples** * Map phone: `{{ trigger.payload.contact.phone }}` * Map contact ID from an upsert step: `{{ steps.create_or_update_contact.contact_id }}` * Map booking slot: `{{ steps.calendly_get_available_times.slots[0].start }}` **Draft vs Live** * **Draft:** run safely with test payloads; **Output -> Refresh** updates schemas. * **Live:** runs on real events. Only switch to Live after your test pass. ## 2) Thoughtly steps (core) These power calls, contacts, and internal data flow. They are the backbone of most automations. ### A) Call Phone Number Call any phone number with a selected ***Agent***. * **Inputs** * **Agent** - choose which agent places the call. * **Phone number** - map from Trigger/Step (for example, `{{ trigger.payload.contact.phone }}`). * **Genius (optional)** - attach a specific knowledge base for this call. You can now select a single Genius source, which prevents context hallucinations and helps manage RAG database sizes. * **Language / Voice (optional)** - override the agent defaults per call. * **Metadata (optional)** - JSON key-values injected into the agent for this call only (see [Attributes vs Metadata](/automations/attributes-vs-metadata)).\ Example: `{"campaign":"q4","lead_source":"typeform","priority":2}` * **Output** - `call_id`, status, timestamps, duration, provider metadata. * **Warnings** * **Refreshing Output places a real call** to the mapped number. Test with internal numbers. * **Outbound calling restrictions**: If you select an agent whose connected phone number has outbound calling disabled, a warning will appear. Enable "Allow Outbound Calls" in the phone number settings to resolve this. * **Typical uses** - ad-hoc callbacks, small pilot campaigns. ### B) Call Contact Call a Thoughtly **Contact** by ID so you can track history and write **Attributes**. * **Why this vs Call Phone Number?** Lets you persist traits as Attributes and reuse them across future calls. * **Prerequisite** - obtain a `contact_id` via **Create or Update Contact** or **Get Contact by Phone Number**. * **Inputs** - `contact_id`, optional Genius (can select a single source to prevent context hallucinations and manage RAG database sizes), Language/Voice, Metadata. * **Output** - same call telemetry plus contact linkage. * **Warnings**: If you select an agent whose connected phone number has outbound calling disabled, a warning will appear. Enable "Allow Outbound Calls" in the phone number settings to resolve this. * **Create or Update Contact** - upsert a contact; returns `contact_id`. * **Get Contact by Phone Number** - fetch to avoid duplicates or enrich calls. * **Add Attributes to Contact** - set persistent key-values (plan, region, lifetime\_value). * **Add Tags to Contact** - apply lightweight labels (vip, pilot). * **Add Disposition** - write a post-call label or result for analytics. * **Get All Contacts** - list contacts for batch processing or export. ### D) Messaging and inbound * **Send SMS** - confirmations, links, follow-ups (map `to`, `body`). * **Connect Inbound Call** - complete the inbound connection after [On Inbound Call](/automations/triggers#thoughtly-on-inbound-call) pre-checks. ### E) Genius source tools Maintain the knowledge base your agents use: * **Add Source to Genius** - add new content to a Genius source. * **Edit Genius Source** - update a source's content or metadata. * **Delete Genius Source** - remove a source from the Genius knowledge base. * **Get Genius Source Content** - fetch the full content for a source. ## Recent action improvements ### Dynamic values in number and date fields Many numeric and date-like fields now support dynamic values from previous triggers or steps. When a field exposes the data picker or custom-value mode, you can insert variables such as: ```text theme={null} {{ steps.calculate_delay.delay_seconds }} {{ trigger.payload.requested_date }} ``` Use dynamic values when call timing, delay duration, appointment date, quantity, or scoring depends on prior workflow data. ### Automatic retry for webhook rate limits When a webhook action receives a `429` response, Thoughtly automatically respects the `Retry-After` header up to the supported retry window and retries once. If the retry succeeds, the automation continues. If it fails again, the run is marked failed. For non-rate-limit errors such as `400` or `500`, design the receiving system and workflow to handle failure explicitly. ### Send Email Use **Send Email** to send email from a connected email channel as part of an automation. Typical uses include confirmations, summaries, follow-ups, or internal notifications. Before using Send Email, configure your email domain and connected addresses in [Email domains](/platform/settings/email-domains). ### Send SMS Use **Send SMS** for confirmations, reminders, and short follow-up messages. If you want the contact to continue a two-way conversation with an agent, use an agent-led SMS conversation pattern rather than treating SMS as a one-off notification. ### Code Use **Code** for advanced transformations and calculations. Code runs in a restricted sandbox and is best for last-mile customization such as normalizing phone numbers, scoring leads, or reshaping webhook payloads. See [Code](/integrations/developer/code). ## 3) AI and logic steps ### A) AI
AI
Extract Fields
Custom Prompt
* **Extract Fields** - structured extraction from text. Example configuration: * Input: `{{ steps.call_contact.transcript }}` * Schema: `{"email":"text","budget":"number","callback_ok":"boolean"}` * **Custom Prompt** - generate a summary, label, or next action; feed into **Conditions**.
### B) Conditions
Condition
🔀
Filter
🔀
If Else
🔀
Switch
🔀
Random Outcome
Deterministic branching and filtering. * **Filter** - drop records that do not qualify. Example: `budget < 100000` -> drop. * **If / Else** - binary branch. Example: `email` matches `/.+@.+\..+/` -> valid path; else ask to re-spell. * **Switch** - multi-way branch. Example: plan in `[basic, pro, enterprise]`. * **Random Outcome** - split traffic for experiments (for example, 80% A and 20% B).
### C) Loop Loop step Iterate over a list (for example, CRM rows) and execute nested steps per item. * **Loop on Items** - iterate over each item in an array and run nested steps. * **Inputs:** array path (for example, `{{ steps.salesforce_query.records }}`), optional batch size, max items. * **Loop variables:** `{{ loop.index }}` (zero-based), `{{ loop.item }}` (current object). * **Example:** loop contacts -> **Call Contact** each -> **Add Disposition** on result. * **Credit usage:** Each iteration of a loop step consumes 1 credit (for AppSumo plans) or counts as 1 automation step, the same as regular automation nodes. #### Conditional logic inside loop nodes You can now add **Conditions** (Filter, If/Else, Switch) directly inside a loop node. This lets you branch or skip steps on a per-item basis without needing a separate outer condition step. **How it works** 1. Inside a **Loop on Items** node, add a **Conditions** step as you would anywhere else in the automation. 2. Reference `{{ loop.item }}` fields in your condition expressions to evaluate each item individually. 3. Each branch inside the loop runs only for items that match its condition; items that do not match follow the else/default branch or are skipped. **Example: call only qualified leads** ```text theme={null} Loop on Items → {{ steps.salesforce_query.records }} └─ If / Else ├─ IF {{ loop.item.lead_score }} >= 80 │ └─ Call Contact │ └─ Add Disposition └─ ELSE (skip — no steps) ``` **Tips** * Use **Filter** inside the loop to drop items early and avoid unnecessary downstream steps. * Use **Switch** when items fall into more than two categories (for example, routing by `loop.item.region`). * Nested conditions count toward the automation step total the same as any other condition node. When the source app supports server-side filters (such as SOQL in Salesforce), filter upstream and keep automation logic simple. Reserve in-loop conditions for logic that depends on per-item data only available at runtime. ## 4) Time utilities * **Delay For** - pause the workflow for a fixed duration (for example, `PT30S`). * **Delay Until** - pause the workflow until a specific timestamp. * **Get Current Time** - return the current time in the selected timezone. * **Get Current Date** - return today's date. * **Get Current Date and Time** - return the current timestamp. * **Convert Timezone** - convert a timestamp between timezones. * **Convert Date and Time Format** - reformat date/time strings (ISO to custom formats). ## 5) Webhook and utility ### Webhook * **Send Webhook** - POST data to external systems. * **Headers:** include auth (for example, `X-API-Token`). * **Idempotency:** send an `event_id`; make downstream receivers idempotent. * **Retries:** design your receiver for retries/backoff. ### Utility * **Get Website Content** - fetch and parse HTML or JSON for enrichment. ## 6) Scheduling and booking integrations Pick the tool your team uses; patterns are similar (availability -> choose slot -> schedule -> confirm). ### Acuity * **Create Appointment** - create a new appointment. * **Update Appointment** - update an existing appointment. * **Cancel Appointment** - cancel an appointment. * **Reschedule Appointment** - move an appointment to a new time. * **Get Available Times** - return available time slots. * **Get Available Dates** - return dates with availability. * **Get Availability in Date Range** - return availability within a date range. * **Get Availability in Date Range for Calendars** - return availability by calendar in a date range. * **Search Appointments** - find appointments by filters. * **Get Appointment Types** - list appointment types. * **Get Calendars** - list calendars. * **Get Forms** - list intake forms. * **Get Form by Appointment Type ID** - fetch the form for a specific appointment type. ### Acuity Enterprise * **Create Appointment** - create a new appointment. * **Update Appointment** - update an existing appointment. * **Cancel Appointment** - cancel an appointment. * **Reschedule Appointment** - move an appointment to a new time. * **Get Available Times** - return available time slots. * **Get Available Dates** - return dates with availability. * **Get Availability in Date Range** - return availability within a date range. * **Get Availability in Date Range for Calendars** - return availability by calendar in a date range. * **Search Appointments** - find appointments by filters. * **Get Appointment Types** - list appointment types. * **Get Calendars** - list calendars. * **Get Forms** - list intake forms. * **Get Form by Appointment Type ID** - fetch the form for a specific appointment type. ### Cal.com * **Check Booking Availability** - check availability for a specific slot or event. * **Create Booking** - create a booking for a selected slot. ### Calendly * **Get Available Times** - fetch bookable times for an event type. * **Schedule Appointment** - schedule a Calendly appointment. * **Get Event Type Availability** - check availability for an event type. * **Get Event Type Availability By Organization** - check availability across an organization. * **Schedule Event** - schedule an event for a user. * **Schedule Event By Organization** - schedule an event within an organization. * **Check Availability** - check host availability for a time range. * **Schedule Event With Reference** - schedule an event with an external reference ID. ### GoHighLevel (scheduling) * **Get Available Times** - retrieve available appointment slots. * **Schedule Appointment** - book an appointment. ### Mindbody * **Get Bookable Times** - fetch available bookable times. * **Get Bookable Time for All Session Types** - fetch availability across session types. * **Add Appointment** - create an appointment. * **Get Locations** - list locations. * **Add Client** - create a client profile. * **Get Client by Email** - find a client by email. * **Get Client by Phone** - find a client by phone number. ### Zoho Bookings * **Create Appointment** - create a new appointment. * **Fetch Appointments** - list appointments by filter or date range. * **Reschedule Appointment** - move an appointment to a new time. * **Delete Appointment** - cancel an appointment. * **Fetch Availability** - retrieve available time slots. **Recipe:** lookup availability -> present or auto-select -> schedule -> **Send SMS** confirmation -> write **Attributes** such as `last_booking_at`. ## 7) CRM and marketing integrations Manage contacts, leads, and deals across systems. Typical pattern: search -> create/update -> note -> follow-up. ### GoHighLevel * **Create Contact** - create a contact record. * **Search for Contact** - search contacts by fields. * **Create Note** - add a note to a contact. * **Retrieve Contact** - get a contact by ID. * **Update Contact** - update contact fields. * **Delete Contact** - delete a contact. ### HubSpot * **Create Contact** - create a new contact. * **Retrieve Contact** - fetch a contact by ID. * **Update Contact** - update contact properties. * **Delete Contact** - delete a contact. * **Search Contact** - search contacts by criteria. * **Get Deal** - retrieve a deal by ID. * **Update Deal** - update deal properties. ### Keap * **Create Contact** - create a new contact. * **List Contacts** - list contacts with optional filters. * **Retrieve Contact** - get a contact by ID. * **Update Contact** - update contact details. * **Delete Contact** - delete a contact. ### Pipedrive * **Create Lead** - create a new lead. * **Update Lead** - update lead details. * **Get Lead** - retrieve a lead by ID. * **Delete Lead** - delete a lead. * **Get Leads** - list leads. ### Salesforce * **Execute SOQL Query** - run a SOQL query and return records. * **Create Object** - create a new object record. * **Update Object** - update an existing object record. * **Delete Object** - delete an object record. * **Add Topic to Object** - add a topic/tag to an object. * **Get Access Token** - generate an access token for API calls. ### Salesforce Sandbox * **Execute SOQL Query** - run a SOQL query and return records. * **Create Object** - create a new object record. * **Update Object** - update an existing object record. * **Delete Object** - delete an object record. * **Add Topic to Object** - add a topic/tag to an object. * **Get Access Token** - generate a sandbox access token for API calls. ### Zoho CRM * **Search Record** - search records by criteria. * **Create Record** - create a new record. * **Update Record** - update a record. * **Delete Record** - delete a record. **Recipe:** trigger on new or changed record -> normalize fields -> **Conditions** route -> if qualified -> **Call Contact** with metadata `{"campaign":"q4"}` -> **Add Disposition** -> update the CRM. ## 8) Collaboration, sheets, and ops ### Slack * **Send Message** - post a message to a channel. * **Send Direct Message** - send a direct message to a user. * **Delete Message** - delete a message. ### SmartSheet * **Get Sheets** - list available sheets. * **Get Row** - retrieve a row by ID. * **Get Sheet** - fetch sheet details. * **Search Sheet** - search rows by query. * **Add Row** - add a row to a sheet. * **Update Row** - update a row. * **Search Column** - find columns by name or ID. ### Trello * **Create Card** - create a card in a list. * **Update Card** - update card fields. ### Zendesk * **Create Ticket** - create a support ticket. **Recipe:** on error or high intent, notify Slack, open a Zendesk ticket, add a SmartSheet row for audit. ## 9) Error handling and resilience * **Happy path:** check explicit success flags (for example, `action_status == "ok"`). * **Retryable:** if transient error and retries \< 2 -> **Delay For** `PT30S` -> retry the step. * **Fallback:** after max retries -> **Send SMS** apology or leverage a ***Transfer node*** in the voice flow; create a ticket. * **Timeouts:** if an action exceeds the SLA, branch to a graceful path and continue. * **Idempotency:** ensure webhook and CRM writes are safe on retry. ## 10) Best practices * Prefer **Call Contact** when you need persistent history and Attributes; use **Call Phone Number** for ad-hoc calls. * Use **Metadata** for per-call context (temporary); use **Attributes** for persistent facts. See [Attributes vs Metadata](/automations/attributes-vs-metadata). * Keep expressions simple; move heavy logic into upstream queries or dedicated **Conditions**. * Add explicit **Else/Default** branches to avoid dead ends. * Test in **Draft** with safe numbers. Remember: **Refreshing Output** on call steps places real calls. ## See also * [Automations - Triggers](/automations/triggers) - where automations start. * [Attributes vs Metadata](/automations/attributes-vs-metadata) - what to store and when. * [Automations overview](/automations/getting-started) - preparing data and contacts before and after calls. * [On Inbound Call trigger](/automations/triggers#thoughtly-on-inbound-call) - logic before connecting inbound calls. # Attributes vs metadata in automations Source: https://docs.thoughtly.com/automations/attributes-vs-metadata Understand the difference between contact attributes and call metadata in Thoughtly so you know what data persists on a contact and what lives per call. If you have built an agent already, you know about **in-agent variables** (from ***Variables*** extraction and mid-call ***Actions*** inside the Agent Builder). Automations add two more ways to pass data into calls and keep it around across calls: **Metadata** and **Attributes**. | Feature | **Metadata** 📝 | **Attributes** 💾 | | ------------------- | --------------------------------------------------- | ------------------------------------------ | | **Scope** | Single call only | Persistent on contact | | **Lifespan** | Temporary (discarded after call) | Permanent (survives across calls) | | **Use cases** | Campaign labels, A/B testing, call-specific context | Customer preferences, status, demographics | | **Set from** | Automation steps (Call Phone Number, Call Contact) | Automations, API, manual contact updates | | **Access in agent** | `{{metadata.VARIABLE_NAME}}` | `{{attributes.VARIABLE_NAME}}` | | **Example** | `campaign: "summer_promo"` | `preferred_language: "spanish"` | | **Think of it as** | A sticky note on this one call | A sticky note on the contact record | Think of them like sticky notes: * **Metadata** = a sticky note **on this one call**. Use it, then toss it. * **Attributes** = a sticky note **on the contact**. It stays for future calls. ## Metadata - short-lived, per-call context You add **Metadata** in an automation step that **places a call** (***Call Phone Number*** or ***Call Contact***). It travels only with that call. **When to use** * Campaign labels you do not need long term (for example `campaign`, `utm_source`) * A/B variant flags (for example `script_version: "B"`) * Temporary hints just for the agent (for example `priority: 2`, `intent: "book_demo"`) **Reference inside the agent** ``` {{metadata.VARIABLE_NAME}} ``` Example: `{{metadata.campaign}}` -> `q4` **Set from automations** Set metadata example In **Call Phone Number** or **Call Contact**, add a JSON object in **Metadata**: ```json theme={null} {"campaign": "q4", "intent": "book_demo", "priority": 2} ``` **Lifecycle** * Exists during the call only. * Not written back to the contact automatically. * If you want to keep it, log a summary or copy values into **Attributes** after the call. ## Attributes - persistent facts about a contact **Attributes** live on the **Thoughtly Contact** record. They are created or updated by steps like **Create or Update Contact** or **Add Attributes to Contact**. **When to use** * Traits you will reuse: `region`, `plan`, `lifetime_value`, `last_booking_at` * Routing decisions across many calls: `vip: true`, `do_not_call_until: "2025-11-01"` * Data you need available for inbound logic (see [On Inbound Call](/automations/triggers#thoughtly-on-inbound-call)) **Reference inside the agent** ``` {{system.contact.attributes.ATTRIBUTE_NAME}} ``` Examples: * `{{system.contact.attributes.region}}` -> `EU Central` * `{{system.contact.attributes.vip}}` -> `true` **Set from automations** Set attributes example Use **Create or Update Contact** (upsert) or **Add Attributes to Contact**. Example payload: ```json theme={null} {"vip": true, "plan": "pro", "lifetime_value": 12450} ``` **Lifecycle** * Sticks to the contact across all future calls (outbound and inbound). * Overwrites on the next update if you send the same key. ## How they work together A practical sequence might look like this: 1. ***Webhook*** trigger arrives with `{ phone, intent }`. 2. **Create or Update Contact** -> set Attributes `{source:"ads", region:"US"}`. 3. **Call Contact** with Metadata `{intent:"book_demo", campaign:"q4"}`. 4. Inside the agent prompt: * "If `{{metadata.intent}}` is `book_demo`, offer times." * "Mention support region `{{system.contact.attributes.region}}`." 5. Post-call (***On Call Completed*** automation, scoped to one agent, multiple agents, or All Agents): * Write `last_called_at` and `last_outcome` as Attributes for reporting. ## Quick Do / Don't **Do** * Use **Metadata** to carry per-call flags (campaign, test group, intent, priority). * Use **Attributes** for facts you will reuse (segment, plan, consent timestamps). * Name keys in `lower_snake_case` (campaign, last\_purchase\_at). * Keep values simple: strings, numbers, booleans, ISO dates. **Don't** * Do not store PII you do not need. * Do not rely on Metadata to be available on future calls; it will not be. * Do not pack huge JSON blobs into Attributes; keep them concise. ## Common patterns * **Campaign calls:** Metadata `{campaign:"spring"}` + Attribute `last_called_at` * **A/B testing:** Metadata `{variant:"B"}` + Attribute `last_variant:"B"` (for long-term tracking) * **Inbound readiness:** Attributes `{plan:"pro", vip:true}` set ahead of time so inbound routing is instant * **Compliance:** Attributes `{consent_sms:true, consent_recorded_at:"2025-10-07"}` ## FAQ **Can I copy Metadata into Attributes?**\ Yes. After the call (***On Call Completed***), add a step to write selected Metadata keys into Attributes. **Which wins if both exist?**\ They do not conflict. Metadata is read-only to the call; Attributes live on the contact. If both define something like `priority`, your prompt decides which to honor. **Where do I see them?**\ Metadata appears in call context and logs. Attributes show on the contact record and can be searched or filtered. ## See also * [Variables](/agents/variables) - in-agent extraction and prompts * [Automations - Steps](/automations/actions) - call steps where you set Metadata and Attributes * [Automations - Triggers](/automations/triggers) - where automations start * [Automations overview](/automations/getting-started) - write results back into Attributes for reporting # Get started with Thoughtly automations Source: https://docs.thoughtly.com/automations/getting-started Build automation workflows that trigger Thoughtly voice agents on a schedule, from CRM events or webhooks, and run post-call actions like tagging and sync.