# Best Practices Source: https://docs.tryhamsa.com/agents/batch-calls/best-practices Guidance for running batch calls effectively Engineer-validated best practices for batch calls will be added here over time. ## General Tips * Test with a small batch (5–10 recipients) before sending to a large list — validates agent behavior and variable substitution without wasting resources * Make sure variable names in your CSV match the variable names your agent references; mismatches are silently ignored * Set a time range that matches your recipients' business hours; calls outside the range are deferred, not skipped ## Related Documentation Learn how to create batch calls Control batch call execution and status Manage recipients and track call statuses # Creating Batch Calls Source: https://docs.tryhamsa.com/agents/batch-calls/creating-batch-calls Step-by-step guide to creating batch calls, uploading recipients, and configuring schedules ## Overview Batch Calls can be created via the Dashboard UI or the API. This guide covers the UI creation process, including CSV upload, validation, and configuration. ## Prerequisites Before creating an batch call, ensure you have: * At least one Voice Agent created and configured * At least one outbound phone number configured * A CSV file with recipient data (at least one valid recipient) ## Basic Information The following fields are required when creating an batch call: ### Batch Call Name **Requirements:** * Required field * 1-100 characters * Descriptive name for identification **Examples:** ``` Good: "Q1 2024 Product Launch Batch Call" Good: "Customer Follow-up - January 2024" Bad: "Batch Call 1", "Test" ``` ### From Number **Requirements:** * Required field * Must be a configured outbound phone number * Number must exist in your account * Number must support outbound calling **Selection:** * Choose from dropdown of available numbers * Only outbound-capable numbers are shown * Number cannot be changed after batch call creation ### Voice Agent **Requirements:** * Required field * Must be a previously created voice agent * Agent must be configured and ready **Selection:** * Choose from dropdown of available agents * Only active agents are shown * Agent cannot be changed after batch call creation The Voice Agent and From Number are locked after batch call creation. If you need to change them, create a new batch call. ## Upload Recipients (CSV) Recipients are added to an batch call via CSV upload. At least one valid recipient is required to proceed. CSV upload interface showing Upload CSV button or drag-and-drop area, file upload zone with instructions, and Download Template link CSV upload interface showing Upload CSV button or drag-and-drop area, file upload zone with instructions, and Download Template link ### File Upload **File Requirements:** * Format: `.csv` file * First row is treated as column headers * No fixed file-size limit enforced at application level * Maximum file size: 50 MB * A downloadable CSV template is available in the UI **Download Template:** * Click the "Download the template" button in the Upload Recipients section * The template includes example columns and sample data * Use the template as a starting point to ensure proper format * You can add or remove columns as needed (see Supported Columns below) **Upload Process:** 1. Download the CSV template (recommended) 2. Fill in your recipient data following the template structure 3. Click "Upload CSV" or drag and drop the file into the upload area 4. File is parsed and validated 5. Validation results dialog opens automatically 6. Review accepted and rejected rows 7. Fix rejected rows if needed 8. Confirm to add recipients The platform validates CSV structure and content automatically. Download the template from the UI to ensure proper format and avoid validation errors. ### Supported Columns The system recognizes the following standard columns (both naming styles are supported): | Field | Accepted Column Names | Required | | --------------------------- | ------------------------------------------------ | -------- | | **Phone Number** | `phoneNumber`, `phone_number` | Yes | | **Name** | `name` | No | | **Ignore E.164 Validation** | `ignoreE164Validation`, `ignore_e164_validation` | No | **Dynamic Variables (External Params):** * Any additional columns are treated as dynamic variables * Dynamic variables have no validation * Are passed as key-value pairs to the agent * Are editable during validation **Example CSV (Template Structure):** | phone\_number | name | ignore\_e164\_validation | dynamic\_variable1 | dynamic\_variable2 | | ------------- | ---------- | ------------------------ | ------------------ | ------------------ | | +12025551234 | John Doe | false | value1 | value2 | | +12025551235 | Jane Smith | false | value3 | value4 | **Template Columns Explained:** * `phone_number` - Required standard column (can also use `phoneNumber`) * `name` - Optional standard column * `ignore_e164_validation` - Optional standard column (can also use `ignoreE164Validation`). Set to `true` to skip E.164 format validation * `dynamic_variable1`, `dynamic_variable2` - Example dynamic variable columns. You can rename these and add as many as needed **Custom Example with Dynamic Variables:** | phone\_number | name | plan | language | region | | ------------- | ---- | ------- | -------- | ------ | | +12025551234 | John | Pro | EN | US | | +12025551235 | Jane | Basic | ES | MX | | +12025551236 | Bob | Premium | FR | CA | In this example: * `phone_number` and `name` are standard columns * `plan`, `language`, and `region` are dynamic variables (custom columns you define) ### Validation Rules #### Phone Number (Required) Each phone number must: * Be present and non-empty * Contain only digits (optional leading `+`) * Be at least 7 digits * Be valid E.164 format (unless `ignoreE164Validation` is set to `true`) **Valid Examples:** ``` +12025551234 12025551234 +442071234567 ``` **Invalid Examples:** ``` 12345 (too short) abc123 (contains letters) (202) 555-1234 (invalid format) ``` #### Name * Optional field * No validation applied * Can be empty * Used for personalization if agent references it #### ignoreE164Validation * Optional field * Boolean value: `true` or `false` * Skips E.164 validation when set to `true` * Useful for international numbers or special formats **Example:** | phone\_number | ignoreE164Validation | | ------------- | -------------------- | | 1234567890 | true | #### Dynamic Variables * Optional fields * Any value accepted * No validation applied * Keys are fixed after upload (values can be edited) ### CSV Validation Results Dialog After upload, a validation dialog opens automatically showing: CSV validation results dialog showing accepted rows section with count, rejected rows section with count, tables showing phone numbers and error messages, Edit buttons, and action buttons CSV validation results dialog showing accepted rows section with count, rejected rows section with count, tables showing phone numbers and error messages, Edit buttons, and action buttons **Dialog Structure:** The validation dialog is organized into two main sections: 1. **Summary Cards (Top):** * **Accepted:** Green card showing count of rows that passed validation * **Rejected:** Red card showing count of rows that failed validation 2. **Tabbed Interface:** * **Accepted Tab:** Displays all rows that passed validation * **Rejected Tab:** Displays all rows that failed validation with error details **Accepted Rows Tab:** * Shows all rows that passed all validations * Displays phone number, name, ignore E.164 validation flag, and dynamic variables * Rows are ready to be added to the batch call * Count is shown in the tab label (e.g., "Accepted (1)") **Rejected Rows Tab:** * Shows all rows that failed one or more validations * Displays detailed validation error messages for each field * Each rejected row has an "Edit" button to fix errors * Count is shown in the tab label (e.g., "Rejected (25)") * Rows must be fixed before they can be added to the batch call ### Editing Rejected Rows Rejected rows can be fixed using the inline editing panel: **Editable Fields:** * **Phone number** - Can be edited to fix validation errors * **Name** - Can be edited or left empty * **ignore E.164 validation** - Toggle checkbox to skip E.164 format validation * **Dynamic variable values** - Values can be edited, but column titles (keys) are fixed and cannot be changed Dynamic variable column titles (keys) are determined by your CSV file headers and cannot be modified in the validation dialog. Only the values can be edited. If you need different column names, update your CSV file and re-upload. **Validation Behavior:** * Validation runs in real-time as you edit each field * Error messages appear immediately below invalid fields * Success indicators appear when fields become valid * All fields must be valid before the row can be saved **Editing Process:** 1. Navigate to the **Rejected** tab in the validation dialog 2. Click the **"Edit"** button (pencil icon) on the rejected row you want to fix 3. An editing panel opens showing all fields for that row 4. Fix the invalid field(s) - validation runs automatically as you type 5. Review validation messages to ensure all errors are resolved 6. Click **"Save"** button (with disk icon) when all fields are valid 7. The row automatically moves to the **Accepted** tab after saving 8. Repeat for other rejected rows if needed **After Fixing Rows:** * Fixed rows appear in the **Accepted** tab immediately after saving * The summary cards update to reflect the new counts * You can continue editing other rejected rows or proceed to add all accepted rows You must fix at least one row if all rows are rejected. The batch call cannot be created with zero valid recipients. ### Final Confirmation Once you have fixed all rejected rows (or are satisfied with the accepted rows): 1. Review the **Accepted** tab to see all rows that will be added 2. Click **"Add Accepted Rows"** button at the bottom right of the dialog 3. All accepted rows are added to the batch call 4. Duplicate phone numbers are checked (warnings shown if duplicates exist) 5. Batch Call form is updated with the recipient count 6. Validation dialog closes automatically You can add accepted rows even if there are still rejected rows remaining. Rejected rows that are not fixed will not be added to the batch call. You can always upload a new CSV file or create a new batch call for those recipients. ### After Adding Recipients After clicking **"Add Accepted Rows"**, a status box appears in the Upload Recipients section showing: Recipients added status box showing recipient count, View Recipients button, and Upload Another CSV button Recipients added status box showing recipient count, View Recipients button, and Upload Another CSV button **Status Box Features:** * **Recipient count:** "You have added X recipient(s)" message with icon * **View Recipients button:** Opens a modal to view and manage all added recipients * **Upload Another CSV button:** Allows you to upload additional CSV files to add more recipients **View Recipients Modal:** Clicking **"View Recipients"** opens a modal dialog titled "Manage Recipients" that displays: * **Table view** showing all added recipients with columns: * Phone number * Name * ignore e164 validation (displayed as Yes/No) * External Params (dynamic variables shown as tags/pills) * **Remove action:** Each row has an 'X' icon to remove that specific recipient * **Save button:** Shows count of recipients (e.g., "Save (1)") to confirm changes * **Cancel button:** Closes the modal without saving changes **Managing Recipients:** * **Remove recipients:** Click the 'X' icon on any row to remove that recipient * **Save changes:** Click **"Save"** to confirm removals and update the recipient count * **Cancel:** Click **"Cancel"** to close without making changes You can only view and remove recipients at this stage. To add more recipients, use the "Upload Another CSV" button to upload additional CSV files. **Upload Another CSV:** * Click **"Upload Another CSV"** to add more recipients from a new CSV file * The same validation process applies to the new CSV file * New recipients are added to the existing list * Recipient count updates to reflect the total number of recipients **Edge Cases:** | Scenario | Behavior | | ----------------------- | --------------------------------- | | Empty CSV | Error shown, cannot proceed | | Parse error | CSV parsing error shown | | All rows rejected | User must fix at least one row | | Duplicate phone numbers | Warning shown, duplicates allowed | ## Scheduling & Time Constraints ### Send Type Batch Calls can be configured with two send types: **Send Now:** * Batch Call is created with status **SCHEDULED** (scheduled to run as soon as possible) * No date/time selection required * The queue and worker fetch batch calls every minute; once picked up, the batch call transitions to **RUNNING** * Respects time range constraints Schedule configuration with Send Now selected showing radio buttons, When Calls Can Run section with time range display Schedule configuration with Send Now selected showing radio buttons, When Calls Can Run section with time range display **Schedule:** * Batch Call starts at selected date & time * Date & time are required * Timezone is required * Batch Call status is SCHEDULED until start time Schedule configuration with Schedule selected showing radio buttons, date and time picker, timezone selector, and When Calls Can Run section Schedule configuration with Schedule selected showing radio buttons, date and time picker, timezone selector, and When Calls Can Run section Both **Send Now** and **Schedule** batch calls appear with SCHEDULED status at first. The queue and worker fetch batch calls every minute. When a batch call is picked up (immediately for Send Now, or at the scheduled time for Schedule), it transitions to RUNNING and begins execution. ### When Calls Can Run (Required) All batch calls must define a time range: **Required Settings:** * Daily start time (e.g., 9:00 AM) * Daily end time (e.g., 6:00 PM) * Allowed days of the week (e.g., Monday-Friday) **Behavior:** * Calls outside this range are deferred, not skipped * Batch Calls continue running but only place calls within the range * Batch Calls cannot be created without a valid time range **Example:** ``` Start Time: 9:00 AM End Time: 6:00 PM Days: Monday, Tuesday, Wednesday, Thursday, Friday Result: Calls only placed weekdays between 9 AM and 6 PM ``` Calls scheduled outside the time range are deferred until the next valid time window. They are not skipped or lost. ## Batch Call Creation Process ### Step-by-Step 1. **Navigate to Batch Calls** * Go to the Batch Calls section in your dashboard * Click "Create" button 2. **Enter Basic Information** * Enter batch call name (1-100 characters) * Select from number (outbound phone number) * Select voice agent 3. **Upload Recipients** * Click "Upload CSV" or drag and drop file * Review validation results * Fix rejected rows if needed * Confirm to add recipients 4. **Configure Schedule** * Choose "Send Now" or "Schedule" * If Schedule: Select date, time, and timezone * Set daily start and end time * Select allowed days of the week 5. **Review and Create** * Review all settings * Check recipient count * Click "Create Batch Call" 6. **Batch Call Starts** * If Send Now: Batch Call status is SCHEDULED until the worker picks it up (every minute); then RUNNING * If Schedule: Batch Call status is SCHEDULED until the scheduled time; worker picks it up every minute, then RUNNING * Monitor progress in batch call details ## Limits & Constraints **Batch Call Creation:** * Batch Call name: Maximum 100 characters * Minimum recipients: 1 * CSV upload required * Time range is mandatory * Agent and phone number must exist **Concurrency:** * Governed by subscription plan * No user management required * Batch Calls always start * Calls queue automatically **CSV:** * No fixed file-size limit * At least one valid recipient required * Standard columns validated * Dynamic variables unlimited ## Next Steps After creating a batch call: 1. **[Monitor Batch Call](./managing-batch-calls)** - Track batch call progress and status 2. **[View Recipients](./recipients-status)** - Check individual call statuses 3. **[Manage Batch Call](./managing-batch-calls)** - Pause, resume, retry, or cancel ## Related Documentation Learn how to control and monitor batch calls Understand recipient management and call statuses Optimize your batch calls # Overview Source: https://docs.tryhamsa.com/agents/batch-calls/introduction Batch outbound calls executed by Voice Agents with scheduling and recipient management ## Overview Batch Calls enable you to execute batch outbound calls using your Voice Agents. Each batch call manages a set of recipients, tracks call progress, and provides comprehensive control over execution. Batch Calls overview showing batch call list table with columns for Batch Call Name, Total Recipients, and Status, multiple batch calls with different statuses, Create button, and search bar Batch Calls overview showing batch call list table with columns for Batch Call Name, Total Recipients, and Status, multiple batch calls with different statuses, Create button, and search bar **Batch Calls enable you to:** * Execute batch outbound calls to multiple recipients * Schedule batch calls for specific times * Track individual call statuses * Personalize calls with dynamic variables * Manage batch call execution (pause, resume, retry, cancel) ## What is an Batch Call? An Batch Call represents a batch of outbound calls executed by the Hamsa platform. Each batch call uses one Voice Agent and one outbound phone number to call one or more recipients. ### Key Capabilities **Batch Call Management** * Create batch calls with CSV recipient uploads * Schedule batch calls for future execution * Monitor batch call progress in real-time * Control batch call execution (pause, resume, cancel) **Recipient Management** * Upload recipients via CSV file * Validate recipient data before execution * Track individual call statuses * Retry failed or unanswered calls **Scheduling & Control** * Schedule batch calls for specific dates and times * Define time ranges when calls can run * Set allowed days of the week * Automatic execution within constraints **Dynamic Personalization** * Pass custom variables per recipient * Personalize agent responses * No validation on dynamic variables * Variables only used if agent references them ## Batch Call Lifecycle Batch Calls move through the following states depending on their send type: | Status | Description | | ------------- | ---------------------------------------------------------------------------------------------------------- | | **SCHEDULED** | Batch call is scheduled to run (Send Now: picked up by worker every minute; Schedule: at future date/time) | | **PENDING** | Batch call is created but not yet started (legacy/retry flows) | | **RUNNING** | Batch call is actively placing calls (shown as "In Progress" in dashboard) | | **PAUSED** | Batch call execution is temporarily stopped by user action | | **COMPLETED** | All recipients have been processed successfully | | **CANCELLED** | Batch call was manually stopped by user action | | **FAILED** | Batch call encountered a fatal error during execution | ### Lifecycle Flow **Send Now:** * SCHEDULED (scheduled to run; queue and worker fetch every minute) → RUNNING (when picked up) → COMPLETED/FAILED * User can PAUSE during RUNNING → PAUSED → Resume to RUNNING * User can CANCEL at any time → CANCELLED * From FAILED/CANCELLED/COMPLETED: Retry → SCHEDULED → continues **Schedule:** * SCHEDULED (waiting for scheduled time; worker fetches every minute) → RUNNING (when time arrives and worker picks it up) → COMPLETED/FAILED * Once RUNNING, follows the same flow as Send Now **Concurrency Impact:** * Batch calls respect account-level concurrent call limits * Multiple batch calls share the concurrency pool * Batch calls queue and execute as capacity becomes available * Execution continues until all recipients are processed Batch Calls are not indefinite and always reach a terminal state. They execute automatically and progress until completion or cancellation. **Note:** The API returns `RUNNING` status, but in the dashboard it is displayed as "In Progress". All other status values match between API and dashboard. ## Prerequisites Before creating an batch call, you must have: **Voice Agent** * At least one Voice Agent created and configured * Agent must be in the Voice Agents section * Agent should be tested and ready for use **Outbound Phone Number** * At least one outbound phone number configured * Number must be available in your account * Number must support outbound calling **Concurrency** * Concurrency is handled automatically by the system * No user management required * Based on your subscription plan limits * Batch Calls always start regardless of current capacity ## Batch Call Components ### Basic Information Each batch call requires: * **Batch Call Name**: 1-100 characters (required) * **From Number**: A configured outbound phone number (required) * **Voice Agent**: A previously created voice agent (required) ### Recipients Recipients are added via CSV upload: * At least one valid recipient required * CSV file with phone numbers and optional data * Validation before batch call creation * Support for dynamic variables ### Scheduling Batch Calls can be: * **Send Now**: Starts immediately * **Schedule**: Starts at selected date & time with timezone ### Time Constraints All batch calls must define: * Daily start and end time * Allowed days of the week * Calls outside range are deferred, not skipped ## Concurrency Behavior Concurrency defines the maximum number of calls that may run in parallel for an batch call. **How It Works:** * Limits are defined by your subscription plan * Users do not see or manage live availability * Batch calls are created as SCHEDULED; the queue and worker fetch them every minute, then they run * Calls are queued and executed as capacity becomes available **Example:** ``` Plan allows 2 concurrent calls: - Only 1 is available at batch call start - Batch call starts immediately with 1 call - Second call starts automatically when capacity frees up ``` Batch Calls never fail or pause due to concurrency limits. They always start and calls execute as capacity becomes available. ## Batch Call Actions Available actions depend on batch call status: | Action | Availability | Description | | ---------- | -------------------------------------------- | -------------------------------- | | **Rename** | Always | Change batch call name | | **Reload** | Always | Fetch latest data from server | | **Pause** | RUNNING | Temporarily stop execution | | **Resume** | PAUSED | Continue paused batch call | | **Retry** | FAILED, CANCELLED, COMPLETED (with failures) | Retry failed or unanswered calls | | **Cancel** | SCHEDULED, PENDING, RUNNING, PAUSED | Stop batch call permanently | | **Delete** | Always | Remove batch call | Pause, Resume, Retry, and Cancel actions require confirmation dialogs to prevent accidental actions. ## Recipient Call Statuses Each recipient in an batch call has a call status: | Status | Meaning | | ---------------- | ----------------------------- | | **PENDING** | Waiting to be processed | | **QUEUED** | In queue waiting for capacity | | **IN\_PROGRESS** | Call is currently in progress | | **COMPLETED** | Call completed successfully | | **FAILED** | Call failed | | **NO\_ANSWER** | Recipient did not answer | ## Dynamic Variables Dynamic variables enable per-recipient personalization: **How It Works:** * Additional CSV columns become dynamic variables * Passed as key-value pairs to the agent * No validation applied * Editable during CSV validation **Important:** * Variables are only used if the Voice Agent explicitly references them * If a variable is not used by the agent, it is ignored * No error is raised if variables are unused * Call behavior is unaffected by unused variables **Example:** | phone\_number | name | plan | language | | ------------- | ---- | ----- | -------- | | +12025551234 | John | Pro | EN | | +12025551235 | Jane | Basic | ES | In this example, `plan` and `language` are dynamic variables that can be referenced by the agent. ## Getting Started 1. **Create a Voice Agent** - Ensure you have a configured agent ready 2. **Configure Phone Number** - Set up an outbound phone number 3. **Create Batch Call** - Use the Batch Calls section to create a new batch call 4. **Upload Recipients** - Upload CSV file with recipient data 5. **Schedule & Configure** - Set schedule and time constraints 6. **Monitor Progress** - Track batch call execution and recipient statuses ## What's Next? * **[Creating Batch Calls](./creating-batch-calls)** - Learn how to create batch calls and upload recipients * **[Managing Batch Calls](./managing-batch-calls)** - Schedule, control, and monitor batch calls * **[Recipients & Status](./recipients-status)** - Understand recipient management and call statuses * **[Best Practices](./best-practices)** - Optimize your batch calls for best results ## Related Documentation Learn about creating and configuring Voice Agents Configure outbound phone numbers Monitor batch call performance Get started with Hamsa platform # Managing Batch Calls Source: https://docs.tryhamsa.com/agents/batch-calls/managing-batch-calls Schedule, control, and monitor batch call execution with pause, resume, retry, and cancel actions ## Overview The Batch Calls list view provides comprehensive management capabilities for all your outbound call batch calls. From here you can create, monitor, and control batch call execution. ## Batch Call List View The batch calls list displays all batch calls in your project with key information: ### Displayed Information | Column | Description | | -------------------- | -------------------------------------- | | **Batch Call Name** | Name of the batch call | | **Total Recipients** | Number of recipients in the batch call | | **Status** | Current batch call status | ### List Actions From the list view, you can: * **Create** a new batch call * **Search** batch calls by name * **Select** an batch call to view details * **Rename** batch calls * **Delete** batch calls ## Batch Call Statuses Batch Calls move through various states: | Status | Description | Actions Available | | ------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------- | | **SCHEDULED** | Batch call is scheduled to run (Send Now: picked up by worker every minute; Schedule: at selected date/time) | Cancel, Delete, Rename, Reload | | **PENDING** | Batch call is created but not yet started | Cancel, Delete, Rename, Reload | | **RUNNING** | Batch call is actively placing calls | Pause, Cancel, Delete, Rename, Reload | | **PAUSED** | Batch call execution is temporarily stopped | Resume, Cancel, Delete, Rename, Reload | | **COMPLETED** | All recipients have been processed | Retry (if failures), Delete, Rename, Reload | | **CANCELLED** | Batch call was manually stopped | Retry, Delete, Rename, Reload | | **FAILED** | Batch call encountered a fatal error | Retry, Delete, Rename, Reload | Batch call statuses are updated in real-time. Refresh the page or use the Reload action to see the latest status. **Note:** The API returns `RUNNING` status, but in the dashboard it is displayed as "In Progress". All other status values match between API and dashboard. ## Batch Call Actions ### Rename **Availability:** Always **Process:** 1. Click the actions menu (⋮) on the batch call 2. Select "Rename" 3. Enter new name (1-100 characters) 4. Save changes Renaming a batch call doesn't affect its execution or recipients. Only the display name changes. ### Reload **Availability:** Always **Behavior:** * Fetches latest data from the server * Shows a loading indicator * Displays a success message on completion * Updates all batch call information **Use Cases:** * Refresh batch call status * Update recipient counts * Get latest progress information * Verify current state ### Pause **Availability:** RUNNING batch calls only **Process:** 1. Click the actions menu (⋮) on a RUNNING batch call 2. Select "Pause" 3. Confirm in the dialog 4. Batch Call status changes to PAUSED **Behavior:** * Stops placing new calls immediately * Calls in progress continue to completion * Batch Call can be resumed later * No data is lost Pausing a batch call requires confirmation. In-progress calls will complete before the pause takes effect. ### Resume **Availability:** PAUSED batch calls only **Process:** 1. Click the actions menu (⋮) on a PAUSED batch call 2. Select "Resume" 3. Confirm in the dialog 4. Batch Call status changes to RUNNING **Behavior:** * Batch Call continues from where it paused * Remaining recipients are processed * Respects time range constraints * Uses available concurrency capacity ### Retry **Availability:** FAILED, CANCELLED, or COMPLETED batch calls (with failures) **Process:** 1. Click the actions menu (⋮) on eligible batch call 2. Select "Retry" 3. Confirm in the dialog 4. Batch Call status changes to SCHEDULED (worker picks up within a minute), then RUNNING **Behavior:** * Uses the same batch call ID * Retries only FAILED and NO\_ANSWER recipients * Completed recipients are skipped * Batch Call restarts with remaining recipients Retry only attempts calls for recipients that failed or didn't answer. Successfully completed calls are not retried. ### Cancel **Availability:** SCHEDULED, PENDING, RUNNING, or PAUSED batch calls **Process:** 1. Click the actions menu (⋮) on eligible batch call 2. Select "Cancel" 3. Confirm in the dialog 4. Batch Call status changes to CANCELLED **Behavior:** * Stops batch call execution permanently * Cannot be resumed (must use Retry instead) * In-progress calls complete before cancellation * Pending calls are not placed Cancelling a batch call is permanent. You cannot resume a cancelled batch call, but you can retry it to attempt failed calls again. ### Delete **Availability:** Always **Process:** 1. Click the actions menu (⋮) on the batch call 2. Select "Delete" 3. Confirm deletion 4. Batch Call is permanently removed Deleting a batch call is permanent and cannot be undone. All batch call data and history will be lost. ## Batch Call Details View Click any batch call to open the details view with comprehensive information. ### Header Actions The batch call header includes quick actions: * **Reload** - Fetch latest data * **Retry** - Retry failed calls (if available) * **Delete** - Remove batch call ### Summary Tab Displays batch call overview: **Information Shown:** * Batch Call status * Total recipients count * Start time * Progress (completed vs total) * Agent name * From number **Progress Indicators:** * Visual progress bar * Completed count * Remaining count * Percentage complete ### Configuration Tab Shows batch call settings: **Displayed Settings:** * Send type (Send Now or Schedule) * Schedule date & time (if scheduled) * Timezone * Time range (start and end times) * Allowed days of the week * Reserved concurrency **Read-Only:** * Configuration cannot be changed after creation * View-only for reference ## Search Functionality ### Searching Batch Calls The search bar allows real-time searching by batch call name: 1. **Enter Search Query** * Type in the search bar * Search is case-insensitive * Searches batch call names only 2. **View Results** * Results update as you type * Matching batch calls are shown * Non-matching batch calls are hidden 3. **Clear Search** * Click the X button or clear the search field * All batch calls are shown again **Example Searches:** ``` "Q1 2024" → Finds batch calls with "Q1 2024" in name "follow-up" → Finds all follow-up batch calls "test" → Finds all test batch calls ``` ## Concurrency Management ### How Concurrency Works **Automatic Management:** * Concurrency limits are defined by your subscription plan * Users do not see or manage live availability * Batch calls are SCHEDULED to run; the worker fetches them every minute, then they start (RUNNING) * Calls are queued and executed as capacity becomes available **Example Scenario:** ``` Plan allows 2 concurrent calls: - Only 1 is available at batch call start - Batch Call starts immediately with 1 call - Second call starts automatically when capacity frees up - Remaining calls queue and execute as capacity becomes available ``` **Key Points:** * Batch Calls never fail due to concurrency limits * Batch Calls never pause due to concurrency limits * All calls eventually execute * Execution may be gradual under high load You don't need to check or manage concurrency. The system handles it automatically based on your subscription plan limits. ## Scheduling Management ### Scheduled Batch Calls **SCHEDULED Status:** * **Send Now:** Batch call is created with SCHEDULED status; the queue and worker fetch batch calls every minute, then it transitions to RUNNING * **Schedule:** Batch call is scheduled for a future date/time; the worker fetches every minute and picks it up when the scheduled time arrives, then it transitions to RUNNING * Shown in list with SCHEDULED status until picked up * Cannot be paused (not running yet) * Can be cancelled before start **Automatic Start:** * The queue and worker fetch batch calls every minute * When a batch call is due to run (Send Now: immediately; Schedule: at scheduled time), the worker picks it up and status changes from SCHEDULED to RUNNING * No manual intervention required ### Time Range Constraints **Deferred Calls:** * Calls outside time range are deferred * Not skipped or lost * Execute when next valid time window arrives * Batch Call continues running **Example:** ``` Time Range: 9 AM - 6 PM, Monday-Friday Batch Call starts Friday at 5:30 PM with 100 recipients Result: - First 10 calls placed immediately (within range) - Remaining 90 calls deferred to Monday 9 AM - Batch Call status remains RUNNING - All calls eventually execute ``` ## Troubleshooting ### Batch Call Stuck in SCHEDULED **Possible Causes:** * Worker runs every minute—batch call may not be picked up yet * Scheduled time hasn't arrived yet (for Schedule type) * System clock issue * Timezone mismatch **Solutions:** * Wait up to a minute for Send Now; worker fetches batch calls every minute * Verify scheduled time and timezone for Schedule type * Check current system time * Cancel and recreate if needed ### Batch Call Not Progressing **Possible Causes:** * All calls are deferred (outside time range) * Concurrency limits reached * Network or system issues **Solutions:** * Check time range settings * Verify concurrency capacity * Use Reload to refresh status * Check for system notifications ### Cannot Perform Action **Possible Causes:** * Action not available for current status * Batch Call in terminal state * Permission issues **Solutions:** * Check batch call status * Verify action availability * Review action requirements * Contact support if persistent ## Next Steps * **[Recipients & Status](./recipients-status)** - Understand recipient management and call statuses * **[Creating Batch Calls](./creating-batch-calls)** - Learn how to create batch calls * **[Best Practices](./best-practices)** - Optimize your batch call management ## Related Documentation Learn how to create batch calls Manage recipients and track call statuses Optimize batch call management # Quick Start Source: https://docs.tryhamsa.com/agents/batch-calls/quick-start Get started with Batch Calls in 5 simple steps ## Overview Get up and running with Batch Calls quickly. Follow these steps to create your first batch call and start making outbound calls. ## Prerequisites Before getting started, ensure you have: * An active project selected * At least one Voice Agent created and configured * At least one outbound phone number configured * A CSV file with recipient data (at least one valid recipient) ## Quick Start Steps 1. **Navigate to Batch Calls** * Go to the [Batch Calls section](https://agents.tryhamsa.com/app/batch-calls) in your dashboard * Or navigate via Dashboard → Batch Calls Batch Calls page overview showing empty state or list of batch calls with Create button prominently displayed Batch Calls page overview showing empty state or list of batch calls with Create button prominently displayed 2. **Create a New Batch Call** * Click **"Create"** button * Enter a descriptive batch call name (1-100 characters) * Select a **From Number** (outbound phone number) * Select a **Voice Agent** to use for the calls 3. **Upload Recipients** * Upload a CSV file with recipient data * Ensure the CSV includes a `phoneNumber` or `phone_number` column * Review validation results and fix any rejected rows * Confirm to add recipients to the batch call 4. **Configure Schedule** * Choose **"Send Now"** to start immediately, or **"Schedule"** for a future date/time * Set daily start and end times * Select allowed days of the week * Review and confirm batch call settings 5. **Monitor Batch Call** * Watch the batch call status change from PENDING → RUNNING * Track individual recipient call statuses * Use pause, resume, or cancel as needed * View detailed progress in the batch call dashboard ## Next Steps Now that you've created your first batch call: * **[Creating Batch Calls](./creating-batch-calls)** - Learn detailed steps for creating batch calls and uploading recipients * **[Managing Batch Calls](./managing-batch-calls)** - Schedule, control, and monitor batch calls * **[Recipients & Status](./recipients-status)** - Understand recipient management and call statuses * **[Best Practices](./best-practices)** - Optimize your batch calls for best results ## Related Documentation Learn more about Batch Call features and capabilities Detailed guide on creating batch calls and uploading recipients How to schedule, control, and monitor batch calls Learn about creating and configuring Voice Agents # Recipients & Status Source: https://docs.tryhamsa.com/agents/batch-calls/recipients-status Manage recipients, track call statuses, and understand call outcomes ## Overview Each batch call contains one or more recipients. The system tracks individual call statuses for each recipient, providing detailed visibility into batch call execution. ## Recipient Call Statuses Recipients move through various call statuses during batch call execution: | Status | Meaning | Description | | ---------------- | --------------------------- | ------------------------------------ | | **PENDING** | Waiting | Recipient is waiting to be processed | | **QUEUED** | In queue | Call is queued waiting for capacity | | **IN\_PROGRESS** | Call in progress | Call is currently active | | **COMPLETED** | Call completed successfully | Call finished successfully | | **FAILED** | Call failed | Call encountered an error | | **NO\_ANSWER** | Recipient did not answer | Recipient did not answer the call | Statuses are updated in real-time as calls progress. Use the Reload action to refresh recipient statuses. ## Status Lifecycle ### Typical Flow ``` PENDING → QUEUED → IN_PROGRESS → COMPLETED ↓ FAILED ↓ NO_ANSWER ``` **Flow Explanation:** 1. **PENDING**: Recipient added, waiting to be processed 2. **QUEUED**: Call queued waiting for available capacity 3. **IN\_PROGRESS**: Call is actively in progress 4. **COMPLETED**: Call finished successfully 5. **FAILED**: Call encountered an error (alternative to COMPLETED) 6. **NO\_ANSWER**: Recipient did not answer (alternative to COMPLETED) ### Status Transitions **Normal Completion:** * PENDING → QUEUED → IN\_PROGRESS → COMPLETED **Failure Paths:** * IN\_PROGRESS → FAILED (call error) * IN\_PROGRESS → NO\_ANSWER (no answer) **Retry Behavior:** * FAILED → PENDING (when batch call is retried) * NO\_ANSWER → PENDING (when batch call is retried) ## Viewing Recipients ### Recipients List The recipients list shows all recipients in the batch call: **Displayed Information:** * Phone number * Name (if provided) * Current status * Dynamic variables (if any) **List Features:** * Sort by status * Filter by status * Search by phone number or name * View call details (for COMPLETED and FAILED) ### Status Filtering Filter recipients by status: * **All** - Show all recipients * **PENDING** - Waiting to be processed * **QUEUED** - In queue * **IN\_PROGRESS** - Currently active * **COMPLETED** - Successfully completed * **FAILED** - Failed calls * **NO\_ANSWER** - No answer ### Status Counts The recipients view displays counts for each status: * Total recipients * Count per status * Progress percentage * Visual status distribution ## Call Details Drawer ### Availability Call details are available only for: * **COMPLETED** recipients * **FAILED** recipients Call details provide comprehensive information about the call outcome, including duration, transcript, and error information. ### Accessing Call Details 1. Navigate to batch call recipients list 2. Find a COMPLETED or FAILED recipient 3. Click on the recipient row 4. Call details drawer opens ### Information Shown **For COMPLETED Calls:** * Call duration * Start time * End time * Call transcript (if available) * Agent responses * User interactions * Dynamic variables used **For FAILED Calls:** * Failure reason * Error message * Attempt time * Failure type * Retry eligibility ## Retry Behavior ### When Batch Calls Are Retried Batch Calls can be retried when: * Batch Call status is FAILED * Batch Call status is CANCELLED * Batch Call status is COMPLETED (with failures) ### Which Recipients Are Retried **Retried:** * **FAILED** recipients * **NO\_ANSWER** recipients **Skipped:** * **COMPLETED** recipients (not retried) Retry uses the same batch call ID and only attempts calls for recipients that failed or didn't answer. Successfully completed calls are preserved and not retried. ### Retry Process 1. Batch Call is retried (via Retry action) 2. Status changes to RUNNING 3. FAILED and NO\_ANSWER recipients change to PENDING 4. COMPLETED recipients remain COMPLETED 5. Batch Call processes retry recipients ## Dynamic Variables ### Overview Dynamic variables are additional data passed to the agent for each recipient. They enable per-recipient personalization. ### How Variables Work **In CSV:** | phone\_number | name | plan | language | | ------------- | ---- | ----- | -------- | | +12025551234 | John | Pro | EN | | +12025551235 | Jane | Basic | ES | **In Batch Call:** * `plan` and `language` are dynamic variables * Passed as key-value pairs to the agent * Available for agent to reference ### Variable Usage **Important:** * Variables are only used if the Voice Agent explicitly references them * If a variable is not used by the agent, it is ignored * No error is raised if variables are unused * Call behavior is unaffected by unused variables **Example:** ``` Agent prompt: "Hello {{name}}, you have a {{plan}} plan." Variables: name="John", plan="Pro" Result: "Hello John, you have a Pro plan." ``` ### Viewing Variables **In Recipients List:** * Dynamic variables shown as columns * Editable during CSV validation * Read-only after batch call creation **In Call Details:** * Variables shown in call information * Values used during call displayed * Helps verify personalization ## Recipient Management ### Adding Recipients **During Creation:** * Upload CSV file * Validate recipients * Fix rejected rows * Confirm to add **After Creation:** * Recipients cannot be added after batch call creation * Create new batch call for additional recipients ### Editing Recipients **Before Batch Call Start:** * Edit during CSV validation * Fix rejected rows * Update dynamic variables **After Batch Call Start:** * Recipients cannot be edited * Data is locked for consistency ### Removing Recipients **Before Batch Call Start:** * Remove rejected rows during validation * Don't add to batch call **After Batch Call Start:** * Recipients cannot be removed * All recipients are processed ## Status Monitoring ### Real-Time Updates **Automatic Updates:** * Statuses update in real-time * No manual refresh needed * Changes appear automatically **Manual Refresh:** * Use Reload action to force refresh * Fetches latest data from server * Updates all recipient statuses ### Progress Tracking **Visual Indicators:** * Progress bar showing completion * Status counts and percentages * Color-coded status indicators **Metrics:** * Total recipients * Completed count * Failed count * No answer count * Pending count * In progress count ## Troubleshooting ### Recipients Stuck in PENDING **Possible Causes:** * Batch Call is PAUSED * Batch Call is SCHEDULED (not started) * All capacity used * Time range constraints **Solutions:** * Check batch call status * Verify time range settings * Wait for capacity * Resume if paused ### High Failure Rate **Possible Causes:** * Invalid phone numbers * Network issues * Agent configuration problems * System errors **Solutions:** * Review failure reasons * Check phone number validity * Verify agent configuration * Contact support if persistent ### Status Not Updating **Possible Causes:** * Real-time updates delayed * Browser cache issues * Network problems **Solutions:** * Use Reload action * Refresh page * Check network connection * Wait a few moments ## Next Steps * **[Managing Batch Calls](./managing-batch-calls)** - Control batch call execution * **[Creating Batch Calls](./creating-batch-calls)** - Learn how to add recipients * **[Best Practices](./best-practices)** - Optimize recipient management ## Related Documentation Control batch call execution and status Learn how to upload and validate recipients Optimize recipient management # Best Practices Source: https://docs.tryhamsa.com/agents/call-history/best-practices Guidance for working with call history effectively Engineer-validated best practices for call history will be added here over time. ## Related Documentation Learn how to filter and search call history Understand call detail information Understand call history fundamentals # Call Details Source: https://docs.tryhamsa.com/agents/call-history/call-details Comprehensive call information with overview, conversation, logs, and outcomes ## Overview The Call Details drawer provides comprehensive information about individual calls, including conversation transcripts, logs, outcomes, and metadata. It's accessible by clicking any call in the call history list. ## Accessing Call Details ### Opening the Drawer **Methods:** * Click any call row in the list * Click "View Details" from actions menu * Exception: PENDING calls do not open drawer **Drawer Behavior:** * Opens as side panel * Overlays the call history list * Can be closed via X button or outside click * Preserves scroll position ## Drawer Tabs The call details drawer includes four main tabs: ### Overview Tab Call details drawer open showing side panel with Overview tab active, Call ID with copy button, Monitor The Call section with Start Live Monitoring button, Call Information section with metadata, and all four tabs visible Call details drawer open showing side panel with Overview tab active, Call ID with copy button, Monitor The Call section with Start Live Monitoring button, Call Information section with metadata, and all four tabs visible **Information Displayed:** * Call metadata (time, duration, cost) * Agent information * Channel type * Status and outcome * Call parameters (user number, agent number) * Basic call statistics **Use Cases:** * Quick call summary * Basic information review * Status verification * Cost tracking ### Conversation Tab **Content:** * Full conversation transcript * Speaker identification * Timestamps for each message * Message formatting * Real-time updates for active calls **Features:** * Scrollable transcript * Search within transcript * Copy transcript option * Export conversation **For Active Calls:** * Live transcription updates * Real-time message display * Auto-scroll to latest * Live indicator * **Send Real-Time Instructions**: After joining the call via "Start Live Monitoring", use the "Send instruction to agent..." input field to send prompts during the ongoing call ### Logs Tab **Information:** * System logs and events * Call flow events * Error messages * Debug information * Timestamped entries **Use Cases:** * Troubleshooting issues * Understanding call flow * Debugging problems * System event tracking ### Outcome Tab **Content:** * Call outcome summary * Results and conclusions * Outcome parameters * Structured data * Outcome metadata **Use Cases:** * Review call results * Extract structured data * Analyze outcomes * Track success metrics ## Monitor The Call For active calls (IN\_PROGRESS status), you can join the call as a listener to monitor the conversation in real-time. ### Before Joining Call details drawer showing Monitor The Call section before joining with section header, description text, large green Start Live Monitoring button with headphone icon, and Overview tab visible Call details drawer showing Monitor The Call section before joining with section header, description text, large green Start Live Monitoring button with headphone icon, and Overview tab visible **Monitor The Call Section:** * Appears in the call details drawer for active calls * Description: "Join the call as a listener to monitor the conversation in real-time" * **"Start Live Monitoring"** button - Click to join the call ### After Joining Call details drawer showing Monitor The Call section after joining with Live Call indicator with green dot, audio controls (Mute and Leave Call buttons), Send instruction to agent input field with helper text and send button Call details drawer showing Monitor The Call section after joining with Live Call indicator with green dot, audio controls (Mute and Leave Call buttons), Send instruction to agent input field with helper text and send button **Interface Updates:** * **"Live Call"** indicator appears with green dot * **Audio controls** become available: * **Mute** button (speaker icon) - Mute/unmute the call audio * **Leave Call** button (red text) - Exit the live monitoring session * **"Send instruction to agent..."** input field appears below audio controls * Helper text: "Send real-time instructions to the agent during the call" * Send button (paper airplane icon) - Submit your instruction **Benefits:** * Monitor conversations in real-time * Hear live audio from the call * Send real-time instructions to guide the agent * View live transcription updates in the Conversation tab Live monitoring is only available for calls with IN\_PROGRESS status. You must join as a listener before you can send real-time instructions to the agent. ## Call Information ### Basic Metadata **Displayed Information:** * **Call ID**: Unique identifier * **Time**: Call timestamp * **Duration**: Total call duration * **Status**: Current call status * **Cost**: Cost in credits * **Channel**: Communication channel ### Agent Information **Details:** * Agent name * Agent ID (copyable) * Agent configuration * Agent settings used ### Channel Information **Details:** * Channel type (Web/Telephone) * Channel-specific metadata * Connection information * Channel quality metrics ### Call Parameters **Parameters:** * User/Client number * Agent number * Additional parameters * Custom variables ## Real-Time Updates ### Active Calls **Live Updates:** * Conversation tab updates in real-time * New messages appear automatically * Status changes reflected immediately * Duration updates live **Indicators:** * "Live" badge on active calls * Real-time transcription indicator * Auto-scroll to latest message * Live status updates ### Status Changes **Updates:** * Status changes update automatically * Transition animations * Visual status indicators * Real-time badge updates ## Sending Real-Time Instructions During an ongoing call (IN\_PROGRESS status), you can send real-time prompts or instructions to the agent. **Instructions can only be sent after joining the call as a listener.** ### How to Send Instructions **Step 1: Join the Call** 1. Open the call details drawer for an active call (IN\_PROGRESS status) 2. In the **Monitor The Call** section, click **"Start Live Monitoring"** 3. You'll join the call as a listener to monitor the conversation in real-time **Step 2: Send Instructions** 1. After joining, the interface updates to show: * **"Live Call"** indicator with green dot * Audio controls (Mute, Leave Call) * **"Send instruction to agent..."** input field appears below the audio controls 2. Type your instruction or prompt in the input field 3. Click the send button (paper airplane icon) to send the instruction to the agent **What You'll See:** * **Before joining**: "Start Live Monitoring" button in the Monitor The Call section * **After joining**: "Live Call" indicator, audio controls, and "Send instruction to agent..." input field * Helper text: "Send real-time instructions to the agent during the call" **Use Cases:** * Provide additional context during the call * Guide the agent's response to specific questions * Update information or correct misunderstandings * Escalate or change call direction * Provide real-time coaching or corrections Real-time instructions are only available for calls with IN\_PROGRESS status. You must first join the call using "Start Live Monitoring" before the instruction input field becomes available. ## Conversation Transcript ### Transcript Format **Structure:** * Speaker identification * Message content * Timestamps * Message types **Example:** ``` [10:30:15] Agent: Hello, how can I help you today? [10:30:20] User: I need help with my account [10:30:25] Agent: I'd be happy to help. What's your account number? ``` ### Transcript Features **Functionality:** * Scrollable view * Search within transcript * Copy to clipboard * Export transcript * Print option **For Active Calls:** * Live updates * Auto-scroll * New message indicators * Real-time display ## Call Logs ### Log Entries **Types:** * System events * Call flow events * Error messages * Debug information * Status changes **Format:** * Timestamped entries * Event type * Event description * Additional details ### Log Analysis **Use Cases:** * Troubleshooting * Understanding call flow * Debugging issues * System monitoring ## Call Outcomes ### Outcome Information **Content:** * Outcome summary * Structured results * Outcome parameters * Success indicators * Result data ### Outcome Types **Varieties:** * Success outcomes * Failure outcomes * Partial outcomes * Custom outcomes ## Join Active Call ### Join as Listener **Functionality:** * Join active calls as listener * Real-time monitoring * No interruption to call * Listen-only mode **Access:** * Available for IN\_PROGRESS calls * "Join Call" button in drawer * Opens call interface * Listener mode activated **Use Cases:** * Quality monitoring * Training purposes * Support assistance * Real-time oversight ## Export Options ### Export Conversation **Options:** * Export transcript * Export as text * Export as PDF * Copy to clipboard ### Export Logs **Options:** * Export log entries * Export as text * Export as JSON * Copy logs ## Drawer Navigation ### Tab Navigation **Methods:** * Click tab headers * Keyboard shortcuts * Tab order navigation * Direct tab access ### Closing Drawer **Methods:** * Click X button * Click outside drawer * Press Escape key * Navigate away ## Limitations ### PENDING Calls **Restriction:** * PENDING calls do not open drawer * No details available yet * Wait for call to start * Refresh to check status ### Export Constraints **Limitations:** * Export size limits * Format restrictions * Data availability * Performance considerations ## Next Steps * **[Viewing Calls](./viewing-calls)** - Learn how to filter and search calls * **[Best Practices](./best-practices)** - Optimize call review process ## Related Documentation Learn how to filter and search calls Optimize call review and analysis Understand call history fundamentals # Overview Source: https://docs.tryhamsa.com/agents/call-history/introduction Comprehensive tracking and management of all voice conversations with filtering, search, and export ## Overview The Call History feature provides comprehensive tracking and management of all voice conversations in the Hamsa platform. It enables you to view, filter, search, and export call records with detailed information about each conversation. **Call History enables you to:** * Track all voice conversations in your project * Filter calls by date, status, channel, and agent * Search calls by ID, user number, or agent ID * Export call data for analysis * View detailed call information * Join active calls as a listener Call History overview showing table with columns for Time, Agent, Channel, Duration, Status, and Cost, with multiple call rows displaying different statuses, search bar, and filter controls Call History overview showing table with columns for Time, Agent, Channel, Duration, Status, and Cost, with multiple call rows displaying different statuses, search bar, and filter controls ## What is Call History? Call History is a comprehensive record of all voice conversations in your Hamsa project. Each call record contains metadata, conversation details, and status information that helps you monitor, analyze, and manage your voice interactions. ### Key Capabilities **Call Tracking** * Records all voice conversations * Tracks metadata (time, duration, cost, status) * Associates calls with Voice Agents * Records channel type (Web, Telephone) **Filtering & Search** * Filter by date range, status, channel, and agent * Search by call ID, user number, or agent ID * Multiple filter combinations * Real-time search results **Export & Analysis** * Export current page or filtered results * CSV format for analysis * Preserves filter settings * Bulk data export **Detailed Information** * Comprehensive call details drawer * Conversation transcripts * Call logs and outcomes * Real-time updates for active calls * Send real-time instructions to agents during ongoing calls ## Call Status Lifecycle Calls move through the following states: | Status | Description | | ---------------- | ----------------------------------------- | | **PENDING** | Call is queued or waiting to start | | **IN\_PROGRESS** | Call is actively in progress | | **COMPLETED** | Call completed successfully | | **FAILED** | Call encountered an error | | **NO\_ANSWER** | Recipient did not answer | | **FORWARDED** | Call was forwarded to another destination | Calls reach terminal states automatically. Status updates happen in real-time for active calls. ## Prerequisites Before viewing call history, you must have: * An active project selected * Appropriate permissions to view call history * At least one completed or in-progress call ## Call Record Information Each call record in the history includes: **Basic Information:** * **Time**: Call timestamp (relative or absolute) * **Agent**: Voice Agent name and ID * **Channel**: Communication channel (Web or Telephone) * **Duration**: Call duration in readable format * **Status**: Current call status with color-coded badge * **Cost**: Cost in credits **Detailed Information:** * Call parameters (user number, agent number) * Conversation metadata * Call logs and transcripts * Outcomes and results ## Default View Settings ### Default Filters On first load, the following statuses are selected by default: * **COMPLETED** * **FAILED** * **IN\_PROGRESS** * **FORWARDED** Default filters can be cleared or modified. Filter settings persist across page navigation via URL parameters. ### Default Sort Calls are sorted by **time (descending)** by default, showing most recent calls first. ## Column Visibility Some columns are hidden by default but can be shown: * **Agent Number** - Hidden by default * **Client Number** - Hidden by default * **Timestamp** - Hidden by default These columns can be toggled via column visibility controls. ## Real-Time Updates **Active Calls:** * Status updates in real-time * Duration updates live * New calls appear automatically * No manual refresh needed **Live Transcription:** * Active calls show live transcription * Updates as conversation progresses * Available in call details drawer ## Scope & Access **Project Scoping:** * Call history is scoped to projects * Only shows calls for selected project * Project selection required **Permissions:** * Requires appropriate permissions * Access controlled by role * Audit trail maintained ## Getting Started 1. **Select Project** - Ensure an active project is selected 2. **Navigate to Call History** - Go to Dashboard → Call History 3. **View Calls** - Browse recent calls with default filters 4. **Filter & Search** - Use filters and search to find specific calls 5. **View Details** - Click any call to see detailed information ## What's Next? * **[Viewing Calls](./viewing-calls)** - Learn how to filter, search, and sort calls * **[Call Details](./call-details)** - Understand call details drawer and tabs * **[Best Practices](./best-practices)** - Optimize your call history usage ## Related Documentation Monitor overall system performance Monitor active calls in real-time Learn about Voice Agents Get started with Hamsa platform # Quick Start Source: https://docs.tryhamsa.com/agents/call-history/quick-start Get started with Call History in 4 simple steps ## Overview Get up and running with Call History quickly. Follow these steps to view, filter, and analyze your voice conversations. ## Prerequisites Before getting started, ensure you have: * An active project selected * Appropriate permissions to view call history * At least one completed or in-progress call ## Quick Start Steps 1. **Navigate to Call History** * Go to the [Call History section](https://agents.tryhamsa.com/app/call-history) in your dashboard * Or navigate via Dashboard → Call History 2. **View Calls** * Browse recent calls in the list view * Calls are sorted by time (most recent first) by default * Default filters show: COMPLETED, FAILED, IN\_PROGRESS, FORWARDED 3. **Filter and Search** * Use date range presets (Today, This Week, This Month, etc.) * Filter by status (COMPLETED, FAILED, IN\_PROGRESS, etc.) * Filter by channel (Web, Telephone) * Search by call ID, user number, or agent ID 4. **View Call Details** * Click any call row to open the details drawer * Explore tabs: Overview, Conversation, Logs, Outcomes * For active calls: Click "Start Live Monitoring" to join as a listener, then use "Send instruction to agent..." to send real-time prompts * Export call data or transcript if needed ## Next Steps Now that you've accessed your call history: * **[Viewing Calls](./viewing-calls)** - Learn detailed steps for filtering, searching, and sorting calls * **[Call Details](./call-details)** - Understand call details drawer and all available information * **[Best Practices](./best-practices)** - Optimize your call history usage for analysis ## Related Documentation Learn more about Call History features and capabilities Detailed guide on filtering, searching, and sorting calls How to view and analyze individual call information Monitor overall system performance # Viewing Calls Source: https://docs.tryhamsa.com/agents/call-history/viewing-calls Filter, search, sort, and paginate call history with comprehensive controls ## Overview The Call History list view provides comprehensive controls for viewing, filtering, searching, and managing call records. All settings are preserved in URL parameters for easy sharing and bookmarking. ## List View The call history list displays all calls in a sortable table format with the following columns: ### Displayed Columns | Column | Description | Default Visible | | ----------------- | ------------------------------------------ | --------------- | | **Time** | Call timestamp (relative or absolute) | Yes | | **Agent** | Voice Agent name with ID | Yes | | **Channel** | Channel type (Web, Telephone) with icon | Yes | | **Duration** | Call duration in readable format | Yes | | **Status** | Current call status with color-coded badge | Yes | | **Cost** | Cost in credits | Yes | | **Agent Number** | Agent phone number | No (hidden) | | **Client Number** | Client/user phone number | No (hidden) | | **Timestamp** | Full timestamp | No (hidden) | ### Row Interactions **Click Behavior:** * Click any row to open call details drawer * Exception: PENDING calls do not open drawer * Drawer shows comprehensive call information **Actions Menu:** * Available for completed calls * View details option * Additional actions as available ## Filtering Filter controls showing date range picker with presets, status filter with checkboxes showing X selected, channel filter button, active filter indicators, and reset button Filter controls showing date range picker with presets, status filter with checkboxes showing X selected, channel filter button, active filter indicators, and reset button ### Date Range Filter Date range filtering supports multiple presets: | Preset | Description | | -------------- | -------------------------------------- | | **All** | No date filter (all time) | | **Last Hour** | Calls from the past hour | | **Today** | Calls from today | | **Yesterday** | Calls from yesterday | | **This Week** | Calls from Sunday to today | | **This Month** | Calls from the first of month to today | | **Custom** | User-selected date range | **Custom Date Range:** * Select start and end dates from calendar * Two-month calendar view * Future dates are disabled Date range picker showing calendar popup with two-month view, preset options, selected date range highlighted, start and end date selection, and Done button Date range picker showing calendar popup with two-month view, preset options, selected date range highlighted, start and end date selection, and Done button * Start date: beginning of day (00:00:00.000) * End date: end of day (23:59:59.999) * Click "Done" to apply selection **Date Range Behavior:** * "All" removes date filtering entirely * Presets are calculated based on user's timezone * Custom ranges respect timezone settings * Date range is stored in URL query parameters ### Status Filter Filter by one or more call statuses: **Available Statuses:** * **COMPLETED** - Call completed successfully * **PENDING** - Call is queued or waiting * **FAILED** - Call encountered an error * **IN\_PROGRESS** - Call is actively in progress * **NO\_ANSWER** - Recipient did not answer * **FORWARDED** - Call was forwarded **Status Filter Behavior:** * Multiple statuses can be selected * Filter values stored in URL query parameters * Default statuses applied on first load (COMPLETED, FAILED, IN\_PROGRESS, FORWARDED) * Filter persists across page navigation ### Duration Filter Filter calls by how long they lasted: **Conditions available:** * Is between (range) * Is greater than (minimum) * Is less than (maximum) * Is equal to (exact) **How to use:** 1. Click the **Duration** filter button 2. Select condition type 3. Enter value(s) in seconds 4. Click Apply ### Channel Type Filter Filter by communication channel: **Available Channels:** * **Web** - Web-based calls * **Telephone** - Phone calls **Channel Filter Behavior:** * Multiple channels can be selected * Filter stored in URL query parameters * Empty values show all channels * Visual icons distinguish channel types ### Agent Filter Filter by Voice Agent: **Selection:** * Select from dropdown of available agents * Shows agent name with truncation for long names * Tooltip shows full name on hover * Empty state shown if no agents available **Agent Filter Behavior:** * Single agent selection * Filter stored in URL query parameters * Agents loaded from project's voice agents * Filter persists across navigation ### Filter Reset **Reset Button:** * Clears all column filters * Resets date range to "All" * Preserves pagination and sorting * URL query parameters updated **Process:** 1. Click "Reset" button 2. All filters cleared 3. Date range set to "All" 4. Status filters reset to defaults 5. Channel and agent filters cleared ## Searching ### Search Functionality **Search Bar:** * Located in table toolbar * Real-time search as you type * Searches across multiple fields **Search Fields:** * **Call ID** - Unique call identifier * **User Number** - User/client phone number * **Agent ID** - Voice Agent identifier **Search Behavior:** * Case-insensitive matching * Search term stored in URL query parameters * Pagination resets when search is active * Search persists across page navigation ### Search Results **Display:** * Filtered results displayed immediately * Empty state shown if no matches * Search term highlighted in results (if applicable) * Result count displayed **Empty State:** * "No search results" message * Clear search option * Suggests checking filters ## Sorting ### Sortable Columns The following columns can be sorted: * **Time** - Call timestamp * **Duration** - Call duration * **Cost** - Call cost in credits ### Sort Behavior **Interaction:** * Click column header to toggle sort direction * Ascending (↑) or Descending (↓) * Sort state stored in URL query parameters * Default sort: time descending (most recent first) **Limitations:** * Only one column can be sorted at a time * Clicking different column changes sort * Clicking same column toggles direction ## Pagination ### Pagination Controls **Default Settings:** * Default page size: 10 items per page * Page size configurable via URL query parameters * Page number stored in URL * Per-page count stored in URL **Controls:** * Previous/Next page buttons * Page number input * Page size selector * Total count display ### Pagination Behavior **Display:** * Total count displayed * Filtered count shown when filters are active * Current page and total pages shown * Page navigation via table controls **URL Management:** * URL updates reflect current page state * Page number in query parameters * Page size in query parameters * Shareable URLs preserve pagination ## Export Functionality ### Export Current Page **Behavior:** * Exports only the calls visible on the current page * Respects current page size * Includes all visible columns * CSV format **Use Case:** * Quick export of visible calls * Limited dataset export * Current view snapshot ### Export with Filters **Behavior:** * Exports all calls matching current filters * Includes all filtered results (not just current page) * Respects all active filters * CSV format **Use Case:** * Export filtered dataset * Bulk data export * Analysis-ready data **Export Process:** 1. Apply desired filters 2. Click "Export" button 3. Select "Export Filtered" or "Export Current Page" 4. CSV file downloads 5. File includes all filtered data ## Column Visibility ### Hidden Columns The following columns are hidden by default: * **Agent Number** - Agent phone number * **Client Number** - Client/user phone number * **Timestamp** - Full timestamp ### Toggle Visibility **Controls:** * Column visibility menu * Toggle individual columns * Show/hide as needed * Preferences not persisted (resets on refresh) ## Duration Formatting Duration is displayed in human-readable format: **Formatting:** * **Seconds**: "30s", "45s" (under 60 seconds) * **Minutes**: "2m 30s", "15m" (60 seconds to 59 minutes) * **Hours**: "1h 30m", "2h" (60+ minutes) **Examples:** ``` 30 seconds → "30s" 2 minutes 30 seconds → "2m 30s" 1 hour 30 minutes → "1h 30m" ``` ## Cost Formatting Cost is displayed in credits with proper formatting: **Formatting:** * Integer values: "5 credits", "10 credits" * Decimal values: "5.5 credits", "10.25 credits" * Consistent decimal precision ## Status Badges Status is displayed with color-coded badges: **Status Colors:** * **COMPLETED** - Green * **IN\_PROGRESS** - Blue * **PENDING** - Yellow * **FAILED** - Red * **NO\_ANSWER** - Orange * **FORWARDED** - Purple ## Channel Display Channels are displayed with icons and badges: **Web Channel:** * Web icon * "Web" badge * Distinct styling **Telephone Channel:** * Phone icon * "Telephone" badge * Distinct styling ## Empty States ### No Calls **Displayed When:** * No calls exist in project * All calls filtered out * Project has no call history **Message:** * "No calls found" * Suggests checking filters * Provides guidance ### No Search Results **Displayed When:** * Search returns no matches * Filters exclude all calls * Search term too specific **Message:** * "No search results" * Clear search option * Suggests adjusting filters ## URL State Management All filters, sorting, and pagination are stored in the URL: **Benefits:** * Shareable URLs * Bookmarkable states * Browser back/forward support * Direct navigation to filtered views **Stored Parameters:** * Date range * Status filters * Channel filters * Agent filter * Search term * Sort column and direction * Page number * Page size ## Real-Time Updates ### Active Calls **Live Updates:** * Status changes update automatically * Duration updates in real-time * New calls appear automatically * No manual refresh needed **Visual Indicators:** * Active calls highlighted * Real-time status badges * Live duration counters * In-progress indicators ## Responsive Design ### Mobile Adaptations **Layout:** * Responsive table layout * Touch-friendly controls * Optimized for small screens * Horizontal scroll when needed ### Touch Interactions **Gestures:** * Swipe to scroll * Tap to select * Long press for actions * Touch-optimized buttons ## Accessibility ### Keyboard Support **Navigation:** * Tab through filters * Arrow keys for sorting * Enter to apply filters * Escape to close dialogs ### Screen Reader Support **Announcements:** * Status changes announced * Filter changes announced * Search results announced * Page changes announced ### RTL Support **Layout:** * Right-to-left layout support * Mirrored controls * Proper text direction * RTL-friendly icons ## Next Steps * **[Call Details](./call-details)** - Understand call details drawer and tabs * **[Best Practices](./best-practices)** - Optimize your call history usage ## Related Documentation Learn about call details drawer Optimize call history usage Understand call history fundamentals # Introduction Source: https://docs.tryhamsa.com/agents/dashboard/introduction Centralized monitoring interface for tracking system activity, performance, and customer satisfaction The Dashboard is your command center for monitoring and analyzing your voice AI system. It provides real-time visibility into active calls, comprehensive performance metrics, and deep insights into customer satisfaction. ## Dashboard Sections The dashboard is organized into four key areas, each designed to answer specific questions about your system: **High-level heartbeat.** View live session counts, total volume trends, and aggregate duration metrics to understand overall system activity at a glance. **Technical health.** Analyze system latency, response times, and reliability to ensure your agents are performing optimally. **Customer sentiment.** Track CSAT scores, Net Promoter Score (NPS), and sentiment analysis to measure user happiness and call resolution effectiveness. **Real-time monitoring.** Watch calls as they happen, view live statuses, and join active sessions as a listener for quality assurance. ## Common Use Cases | Goal | Best Tab | | ------------------------------------- | ----------------------------------------------------------------- | | **"Is the system busy right now?"** | [Overview](/agents/dashboard/overview) (Live Sessions) | | **"Are my agents too slow?"** | [Performance](/agents/dashboard/performance) (Latency Metrics) | | **"Are customers happy?"** | [Satisfaction](/agents/dashboard/satisfaction) (CSAT & Sentiment) | | **"I need to listen to a call now."** | [Live Calls](/agents/dashboard/live-calls) | ## Accessing the Dashboard The Dashboard is the default landing page when you log in to the platform. You can always return to it by clicking **Dashboard** in the main navigation menu. # Live Calls Source: https://docs.tryhamsa.com/agents/dashboard/live-calls Monitor active calls in real-time, join conversations as a silent listener, and view live transcription The Live Calls tab shows all currently active voice AI conversations. You can monitor ongoing calls, join as a silent listener, and view live transcription and performance metrics. Live Calls Dashboard Live Calls Dashboard ## Accessing Live Calls 1. Navigate to **Dashboard** from the main menu 2. Click the **Live calls** tab The view refreshes automatically every 10 seconds, showing all calls currently in progress. Use the **Agent Filter** dropdown to show calls for a specific agent or all agents. Only calls with status "IN\_PROGRESS" appear here. Completed calls move to Call History. ## Call Cards Each active call is displayed as a card showing: * **Agent name**: The voice agent handling the call * **Timestamp**: When the call started * **Duration**: Live counter showing elapsed time * **Channel**: Phone, Web, or WhatsApp * **Status**: "In Progress" indicator * **Join button**: Click to listen in on the call ## Joining a Call You can join any active call as a silent listener — the caller and agent are not aware you're listening. ### How to Join 1. Click the **Join** button on a call card 2. The call details drawer opens on the right 3. Click **Join Call** in the drawer header 4. You're now connected and can hear both sides of the conversation ### While Listening * **Live audio**: Hear both the caller and agent in real-time * **Live transcription**: See the conversation transcribed as it happens, with speaker labels (User/Agent) * **Performance metrics**: View ASR, LLM, TTS, and latency metrics updating in real-time ### Leaving a Call * Click **Leave Call** in the drawer header, or * Close the drawer (X button) The caller's conversation continues normally after you leave. When a call ends while you're listening, the drawer closes automatically with a notification. ## Call Details Drawer The drawer opens on the right side of the screen and contains detailed information about the call. Call Details Drawer - Overview Tab Call Details Drawer - Overview Tab ### Overview * Session ID, status, start time, and duration * Channel type * Performance metrics (ASR, LLM, TTS, Latency) updating in real-time Call Details Drawer - Conversation Tab Call Details Drawer - Conversation Tab ### Conversation * Full live transcript with speaker labels and timestamps * Auto-scrolls to the latest message * After the call ends, an audio recording becomes available with playback controls ### Outcome Populates after the call ends: * AI-generated call summary * Sentiment analysis * Resolution status (Resolved / Escalated) ## Auto-Refresh The call list refreshes every 10 seconds automatically. Auto-refresh pauses when you open a call details drawer and resumes when you close it. ## Troubleshooting ### No Calls Showing * Check the agent filter — it may be set to an agent with no active calls * Calls older than 10 minutes are no longer shown * Verify calls are actually being made to your agents ### Can't Join or Hear Audio * Ensure your browser allows microphone/audio permissions for the site * Check your system volume and audio output device * Use a recent version of Chrome, Firefox, or Edge * Verify your network doesn't block WebRTC connections If issues persist, try leaving and rejoining, or refresh the page. ### Transcription Not Appearing Live transcription typically appears 2-3 seconds after speech. If nothing appears: * Wait a few seconds after joining — connection may still be establishing * Check that someone is actually speaking * Close and reopen the drawer ## Privacy Note You join calls as a silent listener — the caller is not notified. Ensure your use of call monitoring complies with applicable laws and your company's privacy policies. Consider including a monitoring disclosure in your agent's greeting. ## Related View overall system metrics and statistics Search and review completed call recordings Analyze detailed performance data Track customer satisfaction and sentiment # Overview Source: https://docs.tryhamsa.com/agents/dashboard/overview Monitor your voice AI system's overall activity with session counts, durations, and call distribution analytics The Overview tab is your primary view for monitoring overall system activity. It displays real-time metrics and historical data based on your selected filters. Dashboard Overview UI Dashboard Overview UI ### Accessing the Overview 1. Navigate to **Dashboard** from the main navigation menu 2. The **Overview** tab opens by default 3. Use the filter controls at the top to refine your view: * **Agent Filter**: Select "All agents" or a specific voice agent * **Date Range**: Choose from preset ranges or custom dates ## Overall Information Metrics The top section displays four primary metrics: ### Live Sessions The number of concurrent active calls happening right now. ### Total Sessions The total number of completed sessions within your selected date range. ### Average Session Duration The mean duration of all sessions in your selected time range, displayed in minutes and seconds (e.g., "2m 34s"). Very short average durations (under 30 seconds) may indicate call quality issues or premature disconnections. Check your call history to identify the cause. ### Total Session Duration The cumulative time of all sessions combined, displayed in hours and minutes (e.g., "52h 18m"). ## Additional Metrics ### Calls by Duration Bucket Categorizes calls into three duration ranges: * **Less than 30s**: Very short calls (quick queries or disconnections) * **30-120s**: Medium-length calls (standard conversations) * **More than 120s**: Long calls (complex issues or extended interactions) Most calls should fall in the 30-120s range for typical use cases. A high number of calls under 30s may indicate connection issues or callers hanging up quickly. ### Average Words per AI Response The average number of words the AI agent uses in each response. As a reference: * **\< 20 words**: Responses may be too brief to be helpful * **20-60 words**: Typical for natural conversation * **> 80 words**: May overwhelm callers — consider adjusting your prompt to encourage conciseness ### Forwarded to Human Agent The percentage of calls that were escalated to a human agent. As a reference: * **\< 10%**: High AI containment * **10% - 20%**: Acceptable for most use cases * **> 20%**: Agent may need expanded knowledge base or capabilities ## Charts Dashboard Charts UI Dashboard Charts UI ### Calls by Duration Bucket (Pie Chart) Visual distribution of calls across the three duration buckets. Hover over segments to see exact counts and percentages. ### Calls Over Time (Line Chart) Call volume over time, with granularity based on your selected date range: * **Today or Yesterday**: Hourly breakdown * **This Week / This Month**: Daily breakdown * **Custom range**: Automatically adjusts (hourly, daily, weekly, or monthly) Use this chart to identify peak usage hours, spot volume trends, or measure the impact of changes you've made. ## Filtering ### Agent Filter Filter all metrics and charts by a specific agent. Switch between agents to compare their metrics individually. The agent filter is single-select. When "All agents" is selected, you see aggregated data across your entire system. ### Date Range Filter Choose from preset ranges or create custom date ranges: * **Today**: Current day (midnight to now) * **Yesterday**: Previous full day * **This Week**: Sunday to today * **This Month**: First day of month to today * **Custom**: Select any start and end date All times are displayed in your browser's local timezone. ## Troubleshooting ### No Data Available * Verify you have calls in the selected date range * Try selecting "All agents" if a specific agent is filtered * Expand your date range (e.g., from "Today" to "This Week") ### Metrics Show Zero * Your selected date range may have no activity * The filtered agent may have no calls in that period * Wait a few seconds for data to finish loading ### Slow Loading * Reduce the date range — large ranges process more data * Filter by a specific agent instead of "All agents" * Use preset date ranges rather than custom ranges spanning many months ## API Reference Retrieve session counts, durations, and call volume trends. ## Related Monitor active calls in real-time and join as a listener Analyze system performance and response times Track customer satisfaction and sentiment analysis Search and review detailed call logs and transcripts # Performance Source: https://docs.tryhamsa.com/agents/dashboard/performance Monitor your voice AI agent's performance with metrics on speech processing, LLM response times, latency, and error rates The Performance tab provides insights into your voice agent's technical performance. Use it to understand response times, spot issues, and optimize what's within your control. Performance Dashboard UI Performance Dashboard UI ## Accessing Performance Metrics 1. Navigate to **Dashboard** from the main menu 2. Click the **Performance** tab 3. Use the top filters to refine your view: * **Agent Filter**: Select a specific agent or "All agents" * **Date Range**: Choose the time period for analysis ## Key Metrics The Performance tab displays five metrics that measure different aspects of your agent's speed and reliability. ### ASR Processing Time **What it measures**: Time to convert the caller's speech to text (Automatic Speech Recognition). This is the time between the caller finishing speaking and the system having a text transcription ready. Hamsa's ASR engine handles this processing automatically. As a reference, here are typical ranges: * **150ms - 300ms**: Normal * **300ms - 500ms**: Acceptable * **> 500ms**: Investigate If you consistently see high ASR times, this may indicate an issue on our end. [Contact support](https://tryhamsa.com/contact/) if ASR processing time regularly exceeds 500ms. ### LLM Response Time **What it measures**: Time for the AI language model to generate a response after receiving the transcribed text. This is typically the largest portion of overall latency and the metric you have the most control over. It depends on which model you've selected and how your prompts are configured. As a reference, here are typical ranges: * **\< 1,000ms**: Fast * **1,000ms - 2,000ms**: Normal * **2,000ms - 3,000ms**: Acceptable * **> 3,000ms**: Slow — consider optimizing LLM response times above 3,000ms may cause callers to think the system is unresponsive. Aim for under 2,000ms for natural conversation flow. **Factors that affect LLM speed:** * **Model choice**: Larger models (GPT-4.1, Gemini 2.5-Pro) are slower but more capable. Smaller models (GPT-4.1-Mini, Gemini 2.5-Flash) are faster. * **Prompt length**: Longer system prompts and conversation history increase processing time. * **Response length**: Longer generated responses take more time. * **Provider load**: LLM provider APIs can be slower during peak hours. ### TTS Generation Time **What it measures**: Time to convert the LLM's text response into speech (Text-to-Speech). This is the final processing step before the caller hears the response. Hamsa's TTS engine handles this automatically. As a reference, here are typical ranges: * **\< 400ms**: Fast * **400ms - 600ms**: Normal * **600ms - 800ms**: Acceptable * **> 800ms**: Investigate If TTS times are consistently high, [contact support](https://tryhamsa.com/contact/). TTS performance is managed by Hamsa's infrastructure. ### Latency **What it measures**: Total end-to-end response time from when the caller stops speaking to when they hear the agent's reply. ``` Latency = ASR Time + LLM Time + TTS Time + Network Overhead ``` As a reference, here are typical ranges: * **\< 2,000ms**: Excellent * **2,000ms - 3,000ms**: Normal * **3,000ms - 4,000ms**: Acceptable * **> 4,000ms**: Poor — likely impacting conversation quality This is the most important metric for conversation quality. When latency is high, use the breakdown of ASR, LLM, and TTS times to identify which component is contributing the most. ### Error Rate **What it measures**: Percentage of sessions that encountered errors. As a reference, here are typical ranges: * **\< 1%**: Excellent * **1% - 3%**: Normal * **3% - 5%**: Acceptable * **> 5%**: Problematic — investigate A small error rate (1-2%) is normal in production. If you see a sustained rate above 5% or a sudden spike, [contact support](https://tryhamsa.com/contact/). ## Performance Bar Chart The chart displays ASR, LLM, TTS, and Latency metrics side-by-side. Since Latency is the total of all components, focus on comparing the ASR, LLM, and TTS bars to identify which component is contributing the most to overall response time. * **X-axis**: Metric names * **Y-axis**: Time in milliseconds * Hover over bars to see exact values ## Optimizing Performance The primary lever you have for improving performance is **LLM configuration**. ASR and TTS are handled by Hamsa's infrastructure. ### Choose the Right Model Balance speed and quality based on your use case: | Use Case | Recommended Models | Why | | ------------------ | ------------------------------ | -------------------------------------------------------------- | | Simple Q\&A / FAQ | GPT-4.1-Mini, Gemini 2.5-Flash | Fast responses, sufficient quality for straightforward queries | | Customer support | GPT-4.1-Mini, Gemini 2.5-Flash | Good balance of speed and understanding | | Complex advisory | GPT-4.1, Gemini 2.5-Pro | Better reasoning, accepts higher latency | | Sales / high-touch | GPT-4.1-Mini, Gemini 2.5-Flash | Low latency critical for natural conversation | If you're unsure, start with a faster model and only move to a larger one if response quality is insufficient. ### Optimize Your Prompts * **Keep system prompts concise**: Remove unnecessary examples or verbose instructions. Every token adds latency. * **Limit conversation history**: If your agent carries long conversations, consider limiting context to the most recent messages. * **Encourage shorter responses**: Guide the model to be concise through your prompt instructions. Shorter responses generate faster and are easier for callers to follow. ### Bring Your Own Model If you're using a custom OpenAI-compatible endpoint, the LLM response time depends entirely on your provider's performance. Monitor this metric to ensure your provider meets your latency requirements. ## Filtering and Comparison ### By Agent Compare performance across different agents to understand how model and prompt choices affect speed: 1. Select a specific agent from the filter 2. Note the metrics 3. Switch to another agent and compare Differences usually come from model choice, prompt length, or response complexity. ### By Date Range Use date range filters to spot trends or investigate issues: * **Today vs Yesterday**: Detect sudden degradation * **This Week vs Last Week**: Identify trends * **Custom range**: Investigate specific incidents ## Troubleshooting ### High LLM Response Time This is the most common performance issue and one you can address: 1. **Switch to a faster model** — try GPT-4.1-Mini or Gemini 2.5-Flash 2. **Shorten your system prompt** — remove redundant instructions 3. **Reduce conversation history** — less context means faster processing 4. **Check your LLM provider status** — if using a custom endpoint, verify it's performing normally ### High ASR or TTS Times These are managed by Hamsa. If you notice consistently high values: 1. Contact Hamsa support with the affected agent and time range ### Error Rate Spike 1. Check if the issue is specific to one agent or all agents 2. If using a custom LLM endpoint, verify your provider is operational 3. Contact Hamsa support if the issue persists If you experience a sudden spike in errors or latency that doesn't resolve within a few minutes, contact Hamsa support with the affected agent name and approximate time the issue started. ## API Reference Retrieve performance metrics programmatically. ## Related View overall system metrics and statistics Monitor active calls in real-time Review individual call details and metrics Understand how performance impacts customer satisfaction # Satisfaction & Outcome Source: https://docs.tryhamsa.com/agents/dashboard/satisfaction Track customer satisfaction metrics including CSAT scores, NPS, sentiment analysis, first-call resolution rates, and escalation patterns The Satisfaction & Outcome tab shows how well your voice agent is meeting customer needs. Use it to understand satisfaction trends, resolution effectiveness, and where to focus improvements. Satisfaction & Outcome Dashboard Satisfaction & Outcome Dashboard ## Accessing Satisfaction Metrics 1. Navigate to **Dashboard** from the main menu 2. Click the **Satisfaction & Outcome** tab 3. Apply filters to analyze specific segments: * **Agent Filter**: Compare satisfaction across agents * **Date Range**: Track trends over time ## Key Metrics ### CSAT Score **What it measures**: Customer Satisfaction Score — the percentage of calls that received a positive satisfaction rating from post-call surveys. As a reference, here are typical ranges: * **> 85%**: Excellent * **75% - 85%**: Good * **65% - 75%**: Room for improvement * **\< 65%**: Investigate ### NPS (Net Promoter Score) **What it measures**: How likely customers are to recommend your service, on a scale of 0-10. **How it's calculated**: ``` Promoters (9-10) - Detractors (0-6) = NPS (-100 to +100) Passives (7-8) are not counted. ``` As a reference, here are typical ranges: * **> 50**: Excellent * **30 - 50**: Good * **0 - 30**: Acceptable * **\< 0**: More detractors than promoters — investigate ### First-Call Resolution (FCR) **What it measures**: Percentage of calls handled entirely by the AI agent without being transferred to a human. ``` FCR = (Calls Not Transferred to a Human / Total Calls) × 100 ``` A call is counted as resolved when it ends without the agent escalating or handing off to a human. No manual input is needed — this is calculated automatically. As a reference, here are typical ranges: * **> 80%**: Excellent * **70% - 80%**: Good * **60% - 70%**: Acceptable * **\< 60%**: Investigate FCR and Escalation Rate are inversely related. High FCR means the agent is handling most queries independently. ### Escalation Rate **What it measures**: Percentage of calls that required transfer to a human agent. ``` Escalation Rate = (Escalated Calls / Total Calls) × 100 ``` As a reference, here are typical ranges: * **\< 10%**: Excellent — agent handles most queries * **10% - 20%**: Normal for customer support use cases * **20% - 30%**: Acceptable for complex domains * **> 30%**: High — agent may need expanded capabilities The goal isn't zero escalations. Some queries should go to humans. Focus on reducing unnecessary escalations while ensuring smooth handoffs when needed. ### Sentiment Distribution **What it measures**: The emotional tone of customer conversations, analyzed from transcripts. **Displayed as**: A donut chart with three segments: * **Positive**: Satisfied, grateful * **Neutral**: Matter-of-fact, transactional * **Negative**: Frustrated, upset Sentiment analysis must be **enabled per agent** before data appears here. It is off by default. You can turn it on in your agent's settings. A healthy distribution typically looks like: * **Positive**: 60-70% * **Neutral**: 20-30% * **Negative**: 5-15% Sentiment analysis isn't perfect. Sarcasm, cultural differences, and context can cause misclassification. Use it as a directional indicator, not an exact measurement. ## Reading the Sentiment Chart The donut chart uses color-coded segments: * **Yellow-Orange**: Positive sentiment * **Blue**: Neutral sentiment * **Gray**: Negative sentiment Segment size is proportional to the percentage of calls. Hover over segments to see exact percentages. **What to watch for:** * A growing red segment over time suggests declining experience * A dominant gray segment may indicate the agent is functional but not engaging * A sudden shift in any direction warrants investigation ## Improving Your Metrics These metrics reflect how well your agent serves customers. Here's what you can adjust: ### Improve Resolution and Reduce Escalations * **Expand your knowledge base**: If the agent can't answer common questions, add that information * **Add tool integrations**: Give the agent access to systems it needs (order lookup, account info, etc.) * **Refine escalation triggers**: Configure when the agent should hand off vs. attempt to resolve * **Update conversation flows**: If customers frequently get stuck at specific points, improve the flow ### Improve Satisfaction and Sentiment * **Improve prompt instructions**: Guide the agent's tone, empathy, and thoroughness * **Keep responses concise**: Long-winded answers frustrate callers * **Choose the right model**: More capable models (GPT-4.1, Gemini 2.5-Pro) handle nuanced conversations better * **Set clear expectations**: If the agent can't do something, it should say so early rather than frustrating the caller ### Compare Agents to Find What Works Use the agent filter to view metrics for individual agents. If one agent performs significantly better than another: 1. Review its configuration (prompt, model, knowledge base) 2. Identify what's different from lower-performing agents 3. Apply those patterns where appropriate The agent filter is single-select — switch between agents to compare their metrics. When comparing, account for differences in complexity. A simple FAQ agent will naturally have higher FCR and CSAT than one handling complex support queries. ## Filtering and Trends ### By Date Range Use date range comparisons to spot trends: * **Today vs Yesterday**: Detect sudden changes * **This Week vs Last Week**: Identify trends * **Custom range**: Investigate specific incidents or measure the impact of changes you've made A declining trend across metrics often points to a specific change — a new prompt, a model switch, or a knowledge base update that introduced issues. ### By Agent Filter by specific agents to understand per-agent performance. This is particularly useful after making configuration changes to verify they had the intended effect. ## Troubleshooting ### Metrics Not Loading 1. Expand the date range — there may not be enough data in the selected period 2. Select "All agents" to check if data exists for any agent 3. Verify calls have been made in the selected period 4. If the issue persists, [contact support](https://tryhamsa.com/contact/) ### Conflicting Metrics Sometimes metrics seem contradictory (e.g., high FCR but low CSAT). Common explanations: * **High FCR, Low CSAT**: The agent may be marking calls as resolved without truly satisfying the customer. Review the agent's conversation flow. * **Low Escalation, High Negative Sentiment**: The agent may not be escalating when it should. Consider adjusting escalation triggers for frustrated callers. * **Good Sentiment, Low FCR**: The agent may be pleasant but unable to solve problems. Expand its knowledge base or tool access. ## API Reference Retrieve satisfaction scores, sentiment distribution, and outcome metrics programmatically. ## Related View overall system activity and session metrics Analyze technical performance and response times Monitor active calls in real-time Review individual call transcripts and outcomes # Best Practices Source: https://docs.tryhamsa.com/agents/flow-agent/best-practices Guidance for building reliable flow agents This page covers structural and naming conventions for flow agents. Additional best practices from the Hamsa engineering team will be added here over time. ## Node Naming Use descriptive, action-oriented names that make the flow self-documenting: ``` ✅ Welcome_and_Identify_Caller ✅ Collect_Account_Number ✅ Route_by_Issue_Type ✅ Transfer_to_Billing_Specialist ❌ Node 1 ❌ Router ❌ Conversation ``` ## Variable Naming All variable names must be snake\_case (lowercase, underscores, starts with a letter): ``` ✅ customer_name ✅ account_balance ✅ issue_category ❌ customerName (camelCase) ❌ Customer-Name (kebab-case) ❌ customer name (spaces) ``` Use specific, descriptive names rather than generic ones: ``` ✅ account_number, customer_id, payment_status ❌ number, id, status ``` ## Always Include a Fallback Transition Every node that has conditional transitions needs an **Always** transition as a fallback. Without it, the conversation can stall if no conditions match. ```yaml theme={null} Transitions: - Natural: "billing question" → Billing - Natural: "technical issue" → Tech - Always → General_Help # Required fallback ``` ## Use Extracted Variables Carefully Extracted variables are only available after the node that collects them. Do not reference an extracted variable in a transition or node that comes before it in the flow. Global node conditions cannot use extracted variables — use system variables or custom variables there instead. ## Provide Fallback Values in Messages Use fallback syntax when referencing variables that might not be set: ``` "Hello {{customer_name || 'there'}}, your balance is {{balance || 'unavailable'}}." ``` *** ## Next Steps Configure agent-level defaults Learn about all available node types Understand transition types and priority Validate and test your flow # Debugging & Validation Source: https://docs.tryhamsa.com/agents/flow-agent/debugging Validation system, testing flows, troubleshooting common issues, and debugging tools Master the tools and techniques for validating, testing, and debugging your Flow Agents to ensure they work perfectly in production. *** ## Validation System Hamsa's built-in validation system checks your flow for errors before you can save or deploy. ### Real-Time Validation The validation system runs continuously as you build: ```yaml theme={null} Validation Triggers: - When you add/edit a node - When you create/modify a transition - When you connect edges - When you change global settings - Before saving the flow - Before deploying to production ``` ### Validation Indicator ```yaml theme={null} Header Validation Badge: ✅ Green checkmark: No errors ⚠️ Yellow warning: Issues found (non-blocking) ❌ Red X: Critical errors (blocks saving) Click badge to see: - Total error count - Errors grouped by node - Specific error messages - "Focus" button to jump to problematic node ``` ### Validation Categories #### 1. Workflow-Level Errors **Missing Start Node**: ```yaml theme={null} Error: 'Workflow must have exactly one start node' Cause: No start node exists or multiple start nodes Fix: Add a start node or remove duplicates ``` **Empty System Instructions**: ```yaml theme={null} Error: 'System instructions are required' Cause: Global settings system prompt is empty Fix: Add system prompt in global settings Location: Global Settings → System Prompt ``` #### 2. Node-Level Errors **Empty Message**: ```yaml theme={null} Error: 'Message is required' Node: Conversation Node "Welcome_User" Cause: Message field is empty Fix: Add message content ``` **Missing Tool Selection**: ```yaml theme={null} Error: 'Tool selection is required' Node: Tool Node "Lookup_Account" Cause: No tool selected Fix: Click "Select Tool" and choose a tool ``` **Invalid Phone Number**: ```yaml theme={null} Error: 'Invalid phone number format' Node: Transfer Call Node "Transfer_to_Support" Cause: Phone number doesn't match format +1234567890 Fix: Use international format (e.g., +15551234567) ``` **Missing Agent Selection**: ```yaml theme={null} Error: 'Agent selection is required' Node: Transfer Agent Node "Transfer_to_Human" Cause: No agent/agent pool selected Fix: Select an agent from the dropdown ``` #### 3. Variable Errors **Invalid Variable Name**: ```yaml theme={null} Error: "Variable #1: Name must be in snake_case format" Node: Conversation Node "Collect_Info" Cause: Variable named "customerName" (camelCase) Fix: Rename to "customer_name" Valid Format: - Starts with letter - Lowercase only - Underscores allowed - No spaces or special characters Examples: customer_name, account_id, order_total ``` **Missing Variable Name**: ```yaml theme={null} Error: 'Variable #2: Name is required' Node: Tool Node "API_Call" Cause: Variable extraction configured but name is empty Fix: Provide a variable name ``` **Short Description (Conversation Nodes)**: ```yaml theme={null} Error: 'Variable #1: Description must be at least 10 characters' Node: Conversation Node "Get_Details" Cause: Description is "name" (4 characters) Fix: Provide detailed description (e.g., "The customer's full name for account lookup") ``` **Missing Extraction Prompt (Conversation Nodes)**: ```yaml theme={null} Error: 'Variable #3: Extraction prompt is required' Node: Conversation Node "Collect_Phone" Cause: Extraction prompt is empty Fix: Add prompt like "Extract the phone number the customer provides" ``` **Missing JSON Path (Tool Nodes)**: ```yaml theme={null} Error: 'Variable #1: JSON path is required' Node: Tool Node "API_Lookup" Cause: JSON path field is empty Fix: Add JSON path like "$.data.customer.email" ``` #### 4. Transition Errors **Empty Transition Description**: ```yaml theme={null} Error: 'All transitions must have descriptions' Node: Conversation Node "Menu" Cause: Natural language transition has empty prompt Fix: Add condition like "User wants to speak with billing" ``` **Missing Target Node**: ```yaml theme={null} Error: 'Transition target node does not exist' Node: Router "Account_Type" Cause: Transition points to deleted node Fix: Reconnect transition to valid node or delete transition ``` **No Fallback Transition** (Warning): ```yaml theme={null} Warning: 'No fallback transition found' Node: Conversation Node "Categorize_Issue" Cause: No Always transition Impact: User input might not match any condition Fix: Add Always transition as fallback ``` #### 5. Global Node Errors **Missing Global Condition**: ```yaml theme={null} Error: 'Global trigger condition is required' Node: Transfer Agent Node "Transfer_Agent" Cause: isGlobal = true but globalCondition is empty Fix: Add condition like "User wants to speak with a human agent" ``` **Extracted Variable in Global Condition**: ```yaml theme={null} Error: "Global node uses extracted variable '{{account_number}}'" Node: Global Conversation "Account_Specific_Help" Cause: globalCondition references extracted variable Fix: Use only system or custom variables in global conditions ``` #### 6. Tool Override Errors **Empty Parameter Override**: ```yaml theme={null} Error: 'All parameter override values must be filled' Node: Tool Node "Custom_API" Cause: Parameter override enabled but value is empty Fix: Provide override value or disable override ``` **Empty Header Override**: ```yaml theme={null} Error: 'All header override values must be filled' Node: Tool Node "External_Service" Cause: HTTP header override enabled but value is empty Fix: Provide header value or disable override ``` *** ## Validation Popover The validation popover provides detailed information about all errors and warnings. ### Opening the Validation Popover ```yaml theme={null} Location: Top-right header, next to Save button Icon: Red alert circle with error count badge Click: Opens detailed validation panel ``` ### Popover Contents ```yaml theme={null} Sections: 1. Summary - Total error count - "Fix before saving" reminder 2. Workflow-Level Issues - System prompt errors - Start node errors - General configuration issues 3. Node-Specific Issues (Per Node) - Node name and type - "Focus" button (jumps to node on canvas) - List of all errors for that node - Helpful descriptions of each error 4. Global Variable Issues - Duplicate variable names - Variable conflicts - Naming validation errors 5. Quick Tips - Helpful reminders - Common solutions ``` ### Using the Focus Button ```yaml theme={null} Steps: 1. Click validation popover 2. Find the node with errors 3. Click "Focus" button 4. Canvas zooms to that node 5. Node is highlighted 6. Inspector panel opens with node form Result: You're immediately at the problem location ``` *** ## Testing Strategies ### 1. Development Testing **Test as you build**: ```yaml theme={null} After Adding Each Node: 1. Fill in all required fields 2. Check for validation errors 3. Test transitions logic 4. Verify variable extraction After Completing a Branch: 1. Test entire path end-to-end 2. Try invalid inputs 3. Test edge cases 4. Verify error handling ``` ### 2. Call Testing (Test Mode) Use the built-in call testing feature: ```yaml theme={null} Location: Header → "Test Call" button Features: - Make test call to your flow - Real-time node highlighting (shows current node) - Live call logs (see AI decisions) - Variable inspection (view extracted variables) - Transition tracking (see which transitions fired) Test Scenarios: ✓ Happy path (ideal user) ✓ Confused user (unclear inputs) ✓ Difficult user (edge case responses) ✓ Error scenarios (invalid data) ✓ Global node triggers (interrupt flow) ✓ DTMF inputs (keypad presses) ✓ Long silences (timeout behavior) ✓ Multiple interruptions (concurrent events) ``` ### 3. Live Call Logs Real-time debugging during test calls: ```yaml theme={null} Call Log Panel: Location: Right side during test call Shows: - Timestamp for each event - Node entered/exited - Transitions evaluated - Transition results (matched/not matched) - Variables extracted (name and value) - Tool calls (request and response) - LLM decisions (why transition fired) - Errors or warnings Use Cases: - See why a transition didn't fire - Verify variable extraction - Debug tool failures - Understand AI decisions - Track conversation flow ``` *** ## Debugging Tools ### 1. Node Highlighting ```yaml theme={null} During Test Calls: - Current node: Highlighted with animated ring - Previous nodes: Dimmed - Unvisited nodes: Normal opacity Use To: - Verify conversation path - See which nodes were triggered - Identify unexpected routing - Confirm global node triggering ``` ### 2. Variable Inspector ```yaml theme={null} Variables Panel: Location: Right panel during test or edit Shows: - System variables (current_time, call_id, user_number, etc.) - Custom variables (your API-provided vars) - Extracted variables (collected during conversation) Features: - Real-time updates during calls - Type indicators (string, number, boolean) - Value preview - Scope information (global, node-specific) Use To: - Verify variable extraction - Check variable values - Debug template rendering - Validate variable references ``` ### 3. Transition Inspector ```yaml theme={null} Transition Details (in Call Logs): For each transition evaluated: - Transition type (NL, Equation, DTMF, Always) - Condition (full text) - Evaluation result (true/false) - Priority (if applicable) - Target node - Why it matched/didn't match Example: Transition: Natural Language Condition: "User wants to speak with billing" User Input: "I have a billing question" LLM Decision: MATCH Action: Navigate to Billing_Department node ``` *** ## Common Issues and Solutions ### Issue 1: Transition Never Fires **Symptoms**: * Expected transition doesn't trigger * Conversation stuck or goes to wrong path **Debugging Steps**: ```yaml theme={null} 1. Check Transition Priority: - Is there a higher priority transition that matches first? - Check call logs to see which transition actually fired 2. Check Transition Condition: Natural Language: - Is prompt specific enough? - Test with exact user phrasing - Check LLM evaluation in call logs Equation: - Does variable exist? - Is variable value what you expect? - Check operator (equals vs. contains) - Verify type matching (string vs. number) 3. Check Variable Availability: - Was variable extracted before this node? - Check Variables panel for current values - Verify variable name spelling 4. Check Fallback: - Is there an Always transition that's catching everything? - Is it at the right priority (lowest)? Solution Examples: ❌ Priority issue: - Always (priority: 100) catches before Natural Language (priority: 50) ✅ Fix: - Always (priority: 0), Natural Language (priority: 100) ❌ Variable issue: - Equation: account_balance > 1000 - But account_balance doesn't exist yet ✅ Fix: - Add existence check first, or extract variable earlier in flow ``` ### Issue 2: Variable Not Extracted **Symptoms**: * Variable shows as undefined or null * Template `{{variable_name}}` renders as empty **Debugging Steps**: ```yaml theme={null} 1. Check Extraction Configuration: Conversation Node: - Is extraction prompt clear? - Is description detailed enough (10+ chars)? - Is variable name valid (snake_case)? Tool Node: - Is JSON path correct? - Does tool response contain expected field? - Check tool call logs for actual response 2. Check User Input: - Did user actually provide the information? - Check call logs for user utterance - Was input clear and parseable? 3. Check LLM Extraction: - See call logs for extraction attempt - LLM might not have understood input - Extraction prompt might be unclear 4. Check Variable Scope: - Using variable before it's extracted? - Check flow order (extract before use) Solution Examples: ❌ Vague extraction: Prompt: "Get the number" User: "My account is 12345678" Result: LLM doesn't know which number ✅ Fix: Prompt: "Extract the 8-digit account number the customer provides" ❌ Wrong JSON path: Path: $.accountNumber Response: {"data": {"account_number": "12345"}} Result: undefined ✅ Fix: Path: $.data.account_number ``` ### Issue 3: Global Node Not Triggering **Symptoms**: * Say "I want an agent" but transfer doesn't happen * DTMF press doesn't trigger global node **Debugging Steps**: ```yaml theme={null} 1. Check Global Configuration: - Is isGlobal = true? - Is globalCondition filled? - Is globalCondition specific enough? 2. Check Variable Usage: - Does globalCondition use extracted variables? - Only system and custom variables allowed - Check for validation errors 3. Check Trigger Specificity: Natural Language: - Try exact phrasing from globalCondition - Check if condition is too narrow - Check if overlapping with other global nodes DTMF: - Verify key is configured (0-9, *, #) - Check if DTMF is enabled globally - Try pressing key during conversation 4. Check Priority Conflicts: - Is a local transition catching input first? - Local transitions can override global - Check call logs for what matched Solution Examples: ❌ Uses extracted variable: globalCondition: "User needs help with {{account_type}}" Result: Validation error ✅ Fix: globalCondition: "User wants to speak with an agent" ❌ Too narrow: globalCondition: "User says 'transfer me to an agent please'" Result: Only matches exact phrase ✅ Fix: globalCondition: "User wants to speak with a human agent or representative" ``` ### Issue 4: Tool Call Fails **Symptoms**: * Tool node doesn't execute * Error in call logs * Flow doesn't proceed **Debugging Steps**: ```yaml theme={null} 1. Check Tool Configuration: - Is tool selected? - Are all required parameters filled? - Are parameter values valid? 2. Check Tool Response: - Look at call logs → Tool Calls tab - See exact request sent - See exact response received - Check for error messages 3. Check Parameter Templates: - Are variables in templates defined? - Example: "{{account_number}}" - does account_number exist? - Check for typos in variable names 4. Check Tool Availability: - Is tool still available in your account? - Has tool configuration changed? - Try tool in tool testing interface 5. Check Timeout Settings: - Default: 30 seconds - Is tool taking too long? - Increase timeout if needed 6. Check Error Handling: - What's onErrorBehavior setting? - continue: Flow proceeds anyway - retry: Retries N times - fail: Stops flow - Check which path was taken Solution Examples: ❌ Undefined variable in parameter: Parameter: account_id = "{{account_num}}" Variable name: account_number (typo) Result: Sent as empty string ✅ Fix: Parameter: account_id = "{{account_number}}" ❌ Tool timeout: Timeout: 5000ms (5 seconds) Tool takes: 10 seconds Result: Timeout error ✅ Fix: Timeout: 15000ms (15 seconds) ``` ### Issue 5: Message Not Speaking as Expected **Symptoms**: * Message renders incorrectly * Variables show as `{{variable_name}}` instead of value * Message skipped entirely **Debugging Steps**: ```yaml theme={null} 1. Check Message Content: - Is message field filled? - Is messageType set correctly (static vs. prompt)? - Check for template syntax errors 2. Check Variable Availability: - Were variables extracted before this node? - Check Variables panel for current values - Use fallback syntax: {{var || 'default'}} 3. Check Skip Response Setting: - Is skipResponse = true? - This silences the message - Intentional for silent routing 4. Check Voice Settings: - Is voice configured in global settings? - Is voice provider accessible? - Check for voice-related errors in logs 5. Check Message Type: Static: - Speaks message exactly as written - Variables are replaced Prompt: - LLM generates response based on prompt - Check LLM settings - See generated response in call logs Solution Examples: ❌ Variable not available: Message: "Hello {{customer_name}}, your balance is {{balance}}" Variables: customer_name exists, balance doesn't Result: "Hello John, your balance is " ✅ Fix: Message: "Hello {{customer_name}}, your balance is {{balance || 'unavailable'}}" Result: "Hello John, your balance is unavailable" ❌ Unbalanced braces: Message: "Your balance is {{balance}" Result: Validation error ✅ Fix: Message: "Your balance is {{balance}}" ``` *** ## Debugging Workflows ### Workflow 1: New Flow Not Working ```yaml theme={null} Steps: 1. Check validation errors → Fix all red errors → Address warnings 2. Test in call mode → Follow happy path → Check node highlighting 3. Verify variables → Open Variables panel → Confirm extractions work 4. Check transitions → Review call logs → See which transitions fired 5. Test edge cases → Invalid inputs → Unexpected responses 6. Iterate and improve → Fix issues found → Retest ``` ### Workflow 2: Existing Flow Broke After Changes ```yaml theme={null} Steps: 1. Identify what changed → Review recent edits → Compare to last working version 2. Reapply changes incrementally → One change at a time → Test after each change 3. Find breaking change → When issue reappears, you found it → Debug that specific change 4. Fix and test → Correct the issue → Verify fix works ``` ### Workflow 3: Production Issue Reported ```yaml theme={null} Steps: 1. Reproduce the issue → Use test call with same inputs → Try to see the problem yourself 2. Enable debug logging → Turn on detailed call logs → Make test call again 3. Analyze call logs → Find where flow diverged from expected → Check variable values at that point → See which transitions evaluated 4. Identify root cause → Missing validation? → Unexpected user input? → Variable not extracted? → Transition logic wrong? 5. Create fix → Make changes and test thoroughly 6. Deploy fix → Deploy to production → Monitor for recurrence → Document issue and fix ``` *** ## Testing Checklist Before deploying to production, test: ### Basic Functionality * [ ] Happy path works end-to-end * [ ] All nodes are reachable * [ ] All transitions fire correctly * [ ] All variables extract properly * [ ] All tools execute successfully * [ ] All global nodes trigger appropriately ### Error Handling * [ ] Invalid inputs handled gracefully * [ ] Missing variables have fallbacks * [ ] Tool failures don't crash flow * [ ] Timeouts handled appropriately * [ ] User confusion leads to help or transfer * [ ] Max retry limits work correctly ### Edge Cases * [ ] Empty user input * [ ] Very long user input (> 1 minute) * [ ] Rapid repeated inputs * [ ] Interrupting agent mid-sentence * [ ] Long silences (timeout) * [ ] DTMF during voice input * [ ] Switching between voice and DTMF ### User Experience * [ ] Messages are clear and concise * [ ] No awkward pauses or delays * [ ] Confirmations for critical actions * [ ] Easy escape hatches (agent, menu, end) * [ ] Helpful error messages * [ ] Natural conversation flow ### Validation * [ ] No validation errors * [ ] All warnings addressed or acknowledged * [ ] All nodes have names * [ ] All transitions have descriptions * [ ] All variables follow naming convention *** ## Troubleshooting Resources ### Built-in Help ```yaml theme={null} Validation Popover: - Click error to see description - Use "Focus" to jump to problem - Check "Quick Tips" section Call Logs: - Real-time event stream - Transition evaluation details - Variable extraction results - Tool call request/response - LLM decision reasoning Variables Panel: - Current variable values - Variable types - Variable scope - Variable history ``` *** ## Quick Reference ### Validation Error Quick Fixes | Error | Quick Fix | | -------------------------------- | ---------------------------------------- | | "System instructions required" | Add system prompt in global settings | | "Message is required" | Fill message field in conversation node | | "Tool selection required" | Click "Select Tool" and choose a tool | | "Invalid variable name" | Use snake\_case (lowercase, underscores) | | "Variable description too short" | Extend to 10+ characters | | "Missing extraction prompt" | Add extraction prompt for variable | | "Global condition required" | Add globalCondition for global node | | "No fallback transition" | Add Always transition as last option | | "Invalid phone number" | Use international format (+15551234567) | ### Debugging Commands | Tool | Access | Purpose | | ------------------ | ------------------------- | ------------------- | | Validation Popover | Header badge | See all errors | | Test Call | Header button | Live testing | | Call Logs | Right panel (test mode) | Real-time debugging | | Variables Panel | Right panel | Variable inspection | | Debug Panel | Bottom toggle | Detailed state info | | Node Focus | Validation → Focus button | Jump to error | *** ## Next Steps Learn flow design patterns and optimization Master variable usage and troubleshooting Deep dive into transition logic and debugging Complete node documentation and examples # DTMF Features Source: https://docs.tryhamsa.com/agents/flow-agent/dtmf Three DTMF features for keypad interaction in voice agents DTMF (Dual-Tone Multi-Frequency) signaling represents keypad button presses (0-9, \*, #) in telecommunication systems. Hamsa provides **three distinct DTMF features** for different use cases. ## Overview | Feature | Purpose | Availability | Use Case | | ---------------------- | -------------------------- | ------------------------------------ | ------------------------------ | | **Simple Transitions** | IVR menu navigation | Conversation & Start nodes | "Press 1 for Sales" | | **Input Capture** | Collect digit sequences | Conversation & Start nodes\* | Account numbers, PINs | | **Global Triggers** | Universal keypad shortcuts | All nodes (except web\_tool & start) | "Press 0 for operator anytime" | \*Start nodes support DTMF input capture but do not have completion condition UI (timeout/termination/digitLimit). ### DTMF Processing Flow ```mermaid theme={null} graph TD CALL[Call Active] --> DETECT{DTMF Tone
Detected} DETECT -->|Key Pressed| TYPE{Which DTMF
Feature?} TYPE -->|Feature 1| TRANS[Simple DTMF Transition] TYPE -->|Feature 2| CAPTURE[DTMF Input Capture] TYPE -->|Feature 3| GLOBAL[Global DTMF Trigger] TRANS --> CHECK1{Matching
Transition?} CHECK1 -->|Yes| NEXT1[Transition to
Target Node] CHECK1 -->|No| IGNORE1[Ignore Key] CAPTURE --> COLLECT[Collect Digits] COLLECT --> TERM{Termination
Condition Met?} TERM -->|Digit Limit| STORE[Store in Variable] TERM -->|Termination Key| STORE TERM -->|Timeout| STORE TERM -->|No| COLLECT STORE --> CONTINUE[Continue Flow] GLOBAL --> CHECK3{Global Node
with DTMF Key?} CHECK3 -->|Yes| JUMP[Jump to
Global Node] CHECK3 -->|No| IGNORE3[Ignore Key] style TRANS fill:#e1f5ff style CAPTURE fill:#fff4e1 style GLOBAL fill:#ffe1f5 style STORE fill:#e1ffe1 style JUMP fill:#e1ffe1 ``` ### DTMF Feature Comparison ```mermaid theme={null} graph LR subgraph "Feature 1: Simple Transitions" F1[User presses key
→ Route to node
IVR menu navigation] end subgraph "Feature 2: Input Capture" F2[User enters sequence
→ Store in variable
Account numbers, PINs] end subgraph "Feature 3: Global Triggers" F3[User presses key
→ Jump to global node
Press 0 for operator] end CALL[Phone Call] --> F1 CALL --> F2 CALL --> F3 style F1 fill:#e1f5ff style F2 fill:#fff4e1 style F3 fill:#ffe1f5 ``` *** ## Feature 1: Simple DTMF Transitions **Always available** on conversation and start nodes. No toggle or special configuration required. ### Purpose Enable IVR-style menu navigation where users press a single key to select an option and advance to a specific node. ### How It Works Create menu options like "Press 1 for Sales, Press 2 for Support" by adding DTMF transitions to your nodes. ### Configuration On a conversation or start node, click "+ Add Transition" Choose "DTMF" as the transition type Click a key on the 3×4 keypad grid (0-9, \*, #) Draw an edge to the target node ### Example ```yaml theme={null} Conversation Node: 'Welcome! Press 1 for Sales, Press 2 for Support' ├─ Transition: DTMF key=1 → Sales_Department └─ Transition: DTMF key=2 → Support_Department ``` Use descriptive auto-generated labels like "Press 1" for clarity in your flow diagram. *** ## Feature 2: DTMF Input Capture Available on **conversation nodes and start nodes**. Requires variable name when enabled. **Note:** Start nodes support DTMF input capture but do not display completion condition UI (timeout/termination/digitLimit). These conditions only appear on conversation nodes. ### Purpose Capture a sequence of DTMF digits (account number, PIN, phone number) and store it in a variable for use throughout your workflow. ### How It Works When enabled, the AI listens for multiple keypad presses and stores the complete sequence in a named variable. Capture completes based on optional conditions. ### Configuration Open conversation node form → Find "DTMF Input Capture" → Toggle ON Enter variable name (required): `account_number`, `pin_code`, etc. **Must follow snake\_case format**: lowercase, underscores allowed, starts with letter Set optional conditions (at least one recommended): * **Digit Limit**: Stop after X digits (1-20) * **Termination Key**: Stop when user presses #, \*, or 0-9 * **Timeout**: Stop after X seconds of no input (1-30) ### Schema ```typescript theme={null} { enabled: boolean, variableName: string, // Required: ^[a-z][a-z0-9_]*$ digitLimit?: number, // Optional: 1-20 terminationKey?: '0'-'9'|'#'|'*', // Optional timeoutMs?: number // Optional: 1000-30000 } ``` ### Variable Usage DTMF captured variables are **fully integrated** into the variable system and available to all downstream nodes. Once captured, use the variable in: * **Message templates**: `"Your account number is {{account_number}}"` * **Tool parameters**: Pass to API calls * **Router conditions**: Branch based on value * **Subsequent prompts**: Reference in any downstream node ### Example ```yaml theme={null} Node: Account_Lookup Message: "Please enter your 6-digit account number followed by pound" DTMF Input Capture: enabled: true variableName: account_number digitLimit: 6 terminationKey: # timeout: 15 seconds → User enters: 1-2-3-4-5-6-# → Variable {{account_number}} = "123456" Next Node (Tool): API Call: lookup_customer Parameters: account_id: {{account_number}} ``` The captured variable appears on the node with a phone icon badge for easy identification. **DTMF Capture Restriction:** When DTMF input capture is enabled on a node, number keys (0-9) **cannot be used** for DTMF transitions on that same node. Only **#** and **\*** keys remain available for menu navigation. This prevents conflicts between digit capture and menu options. *** ## Feature 3: Global Node DTMF Triggers Available on all node types except **web\_tool** and **start** nodes. ### Purpose Allow global nodes to be triggered from anywhere in the workflow by pressing a specific key, providing quick access to critical functions. ### How It Works When a node is marked as global with DTMF trigger type, pressing the configured key from anywhere in the call immediately activates that node. ### Configuration Open any node form → Find "Global" section → Toggle ON Choose between: * **Natural Language (Prompt)**: Triggered by speech * **Keypad Press (DTMF)**: Triggered by key press If DTMF selected, choose key from keypad grid **Common conventions:** * 0: Operator/human agent * 9: Repeat main menu * \*: Go back/previous menu * \#: Confirm/submit ### Schema ```typescript theme={null} { isGlobal: true, globalConditionType: 'dtmf', // or 'prompt' globalDtmfKey: '0', // Required when type='dtmf' } ``` ### Examples #### Operator Transfer (DTMF 0) ```yaml theme={null} Transfer Call Node (Global): isGlobal: true globalConditionType: dtmf globalDtmfKey: 0 phoneNumber: +1-800-OPERATOR → User can press 0 anytime to reach operator ``` #### Repeat Menu (DTMF 9) ```yaml theme={null} Conversation Node (Global): isGlobal: true globalConditionType: dtmf globalDtmfKey: 9 message: "Main menu: Press 1 for Sales, 2 for Support" → User can press 9 anytime to hear menu again ``` #### Emergency Support (DTMF \*) ```yaml theme={null} Transfer Call Node (Global): isGlobal: true globalConditionType: dtmf globalDtmfKey: * phoneNumber: +1-800-EMERGENCY → User can press * anytime for emergency support ``` *** ## Roadmap **Outbound IVR Navigation** — the ability for agents to automatically navigate external IVR phone trees when making outbound calls — is not yet available. It is on the roadmap and will be supported in a future release. *** ## Complete IVR Flow Example Here's a comprehensive example combining all three DTMF features: ```mermaid theme={null} graph TD Start[Start Node: Main Menu
Press 1=Sales, 2=Support, 0=Operator] Sales[Sales Node:
Enter Customer ID] Support[Support Node] Lookup[Tool: Lookup Customer] Operator[Global: Transfer to Operator
DTMF Key: 0] Menu[Global: Repeat Menu
DTMF Key: 9] Start -->|DTMF: 1| Sales Start -->|DTMF: 2| Support Sales -->|Capture: customer_id| Lookup Start -.->|DTMF: 0 (anytime)| Operator Start -.->|DTMF: 9 (anytime)| Menu ``` **Implementation:** ```yaml theme={null} Start Node (Conversation): message: "Welcome! Press 1 for Sales, 2 for Support, 0 for operator" transitions: - type: dtmf, key: 1 → Sales_Node - type: dtmf, key: 2 → Support_Node Sales Node (Conversation): message: "Please enter your customer ID followed by #" dtmfInputCapture: enabled: true variableName: customer_id terminationKey: # timeout: 15s transitions: - type: always → Lookup_Tool Lookup Tool (Tool): tool: lookup_customer parameters: id: {{customer_id}} # Uses captured DTMF variable Operator Node (Transfer Call - Global): isGlobal: true globalConditionType: dtmf globalDtmfKey: 0 phoneNumber: +1-800-OPERATOR Repeat Menu Node (Conversation - Global): isGlobal: true globalConditionType: dtmf globalDtmfKey: 9 message: "Main menu: Press 1 for Sales, 2 for Support" ``` *** ## Validation DTMF features are validated at both node and workflow levels. Errors prevent saving until resolved. ### Validation Rules | Feature | Field | Requirement | Error | | --------------------- | ------------- | ----------------------- | -------------------------- | | **Input Capture** | Variable Name | Required when enabled | Must be snake\_case format | | **Simple Transition** | DTMF Key | Required | Must select a key | | **Global Trigger** | DTMF Key | Required when type=dtmf | Must select a key | ### Error Indicators * **Node level**: Red icon in node header * **Workflow level**: Errors in workflow header dropdown * **Focus button**: Navigate to problematic nodes *** ## Troubleshooting **Possible causes:** * Key not selected in popover * Transition not connected to target node * Using on unsupported node type (not conversation/start) **Solution:** Verify key selection and node connections **Possible causes:** * User didn't enter any digits * Timeout occurred before input * Variable name typo in usage **Solution:** Add validation, check variable name syntax **Possible causes:** * Node not marked as global * DTMF key not configured * Trigger type set to 'prompt' instead of 'dtmf' **Solution:** Verify global settings and trigger type **Possible causes:** * Missing variable name when input capture enabled * Invalid variable name format * DTMF key not selected **Solution:** Check workflow header dropdown, click "Focus" to navigate to errors *** ## Next Steps Learn how to use captured variables throughout your flow Master all transition types including DTMF Use captured variables in routing logic Learn flow agent best practices # Global Nodes Source: https://docs.tryhamsa.com/agents/flow-agent/global-nodes Create nodes accessible from anywhere in the flow via natural language or DTMF Global nodes can be triggered from **any point in your conversation flow** — they don't need an explicit edge from another node. Use them for scenarios that can arise at any moment in a conversation, like transferring to a human agent or returning to the main menu. ## How to Create a Global Node Any node type except the Start node can be made global. Open a node's settings and toggle **Global** on. When global is enabled, you choose a **trigger type** — either a natural language condition or a DTMF key. **Prompt trigger:** The LLM evaluates a natural language condition at every conversation turn. ``` Global condition: "The user wants to speak with a human agent or representative" ``` **DTMF trigger:** The node activates when the user presses a specific keypad key. *** ## Configuration | Setting | Description | | ------------------------- | ------------------------------------------------------------------- | | **isGlobal** | Toggle to enable global status | | **globalConditionType** | Trigger type: `prompt` (natural language) or `dtmf` (keypad key) | | **globalCondition** | Natural language trigger condition (when type is `prompt`) | | **globalDtmfKey** | Keypad key: 0–9, \*, # (when type is `dtmf`) | | **globalReturnToSource** | Return to the node the user was on before the global node triggered | | **requiresDoubleConfirm** | Ask user to confirm before executing | | **skipResponse** | Execute the node silently without speaking its message | ### Variable Restrictions Global conditions support **system variables** and **custom variables** only. Extracted variables (collected during the conversation) cannot be used — the global node may be triggered before those variables exist. → See [Variable System](/agents/variables/introduction) for the full list of available system variables. *** ## Double Confirmation When `requiresDoubleConfirm` is enabled, the agent asks the user to confirm before the node executes. ``` User: "I want to end the call" Agent: "Are you sure you want to end this call?" User: "Yes" → End call executes ``` Use this for irreversible actions like ending a call, canceling an appointment, or deleting data. *** ## Skip Response When `skipResponse` is enabled, the node executes without speaking its message. Useful for silent routing — for example, a global router node that checks variables and routes to the right destination without saying anything to the user. *** ## Global DTMF Triggers Global nodes can be triggered by keypresses from anywhere in the flow, in addition to (or instead of) natural language. ``` Press 0 → Transfer to Operator Press 9 → Return to Main Menu ``` Announce these shortcuts to users in your welcome or menu messages so they know they're available. → See [DTMF Features](./dtmf) for full documentation. *** ## Common Examples **Transfer to human agent** ``` Type: Transfer Agent Global condition: "The user wants to speak with a human agent or representative" DTMF trigger: 0 ``` **Return to main menu** ``` Type: Conversation Global condition: "The user wants to return to the main menu or start over" DTMF trigger: 9 ``` **End call** ``` Type: End Call Global condition: "The user wants to end the call or hang up" Require double confirmation: Yes ``` *** ## Next Steps Control how conversations move between nodes Full documentation for keypad interactions Understand variable scoping and availability Explore all available node types # Global Settings Source: https://docs.tryhamsa.com/agents/flow-agent/global-settings Configure agent-level defaults for voice, LLM, knowledge base, and call behavior Global settings define the default behavior for your entire flow agent. These defaults apply across all nodes unless overridden at the node level. ## Overview Global settings are organized into these categories: | Category | Purpose | | ---------------------- | ---------------------------- | | **System Prompt** | Core AI instructions | | **Voice Settings** | Default voice for all nodes | | **LLM Settings** | Default language model | | **Noise Cancellation** | Audio processing | | **Knowledge Base** | RAG data sources | | **MCP Tools** | Globally available tools | | **Outcome** | Call result tracking | | **Phone Number** | Assigned phone numbers | | **Call Settings** | Timing and behavior defaults | | **Webhook** | External event notifications | *** ## System Prompt The system prompt defines the agent's identity, behavior, and constraints. It applies across all conversation nodes unless a node has its own prompt that overrides it. System prompt is **required**. Your flow cannot be saved without it. The default value is `You are a helpful assistant that will answer users questions.` The system prompt supports **system variables** and **custom variables** only. Extracted variables (collected during conversation) are not available here. ### Enhanced Turn Taking Toggle to enable better numeral capturing and backchannel detection for more natural conversations. **Default:** Off ### Prompt Enhancer Controls automatic prompt enhancements applied to your system prompt. | Option | Description | | ------------------- | ------------------------------------------- | | **Disabled** | No enhancements — your prompt is used as-is | | **Basic** (default) | Stable, model-agnostic prompt enhancements | | **Advanced** | Model-aware prompts with live flow context | ### Example ``` You are a customer service representative for Acme Corp. Today is {{current_date}} and the time is {{current_time}}. The caller's number is {{user_number}}. Working hours: {{working_hours}} ``` → See [Writing Effective Prompts](../single-prompt/write-prompt) for full guidance on structuring prompts and using variables. *** ## Voice Settings Select a voice from Hamsa's voice library. The selected voice is the default for all nodes; individual nodes can override it. Voice configuration works the same way as in single-prompt agents. ### Expressiveness Controls the emotional range and variation of the voice. **Range:** 0.0–2.0 **Default:** 1.0 ### Voice Dictionaries Attach pronunciation dictionaries for specialized terms (brand names, technical jargon, foreign words). Dictionaries are managed in the Voices section and selected here. ### STT Model Select the speech-to-text model for transcription. | Model | Description | | -------------------------- | --------------------------------- | | **Hamsa-STT-S2** (default) | Stable Arabic/English recognition | | **Hamsa-STT-S3-beta** | Most recent model (beta) | | **Hamsa-STT-English** | English-focused recognition | → See [Voice Settings](../single-prompt/voice-settings) for full details on browsing, filtering, previewing, and selecting voices. *** ## LLM Settings Configure the default language model for your flow. Individual nodes can override the model and temperature. ### Provider and Model | Provider | Models | | -------------------- | --------------------------------------------------------------------------------------- | | **OpenAI** (default) | GPT-5, GPT-5-Mini, GPT-5-Nano, GPT-4.1, GPT-4.1-Mini, GPT-4.1-Nano, GPT-4o, GPT-4o-mini | | **Gemini** | Gemini 2.5-Pro, Gemini 2.5-Flash, Gemini 3.0 Flash Preview, Gemini 3.1 Flash Lite | | **Groq** | GPT-120-OSS, GPT-20-OSS | | **DeepMyst** | gpt-4.1-optimize, gpt-4.1-mini-optimize | | **Custom** | Any OpenAI-compatible endpoint (requires base URL and API key) | Default: **Gemini 3.1 Flash Lite** ### Temperature Controls response variability. **Range:** 0.0–1.0 **Default:** 0.2 GPT-5 family models (GPT-5, GPT-5-Mini, GPT-5-Nano) require temperature = 1.0. This is enforced automatically when you select a GPT-5 model. ### Node-Level Overrides Model and temperature can be overridden per conversation node. This lets you use a more capable model for complex reasoning nodes and a lighter model for simple confirmations. *** ## Noise Cancellation Removes background noise from the caller's audio. **Model:** * **Disabled** — No noise cancellation * **Telephony Optimized** — Optimized for phone call audio * **General Use Cases** — Broader noise cancellation **Granularity** (when enabled): * **Per Conversation** — Apply once for the entire call * **Per Turn** — Apply to each speaking turn separately **Additional options:** * **Auto Gain Control** — Normalize audio volume levels * **Send Denoised to STT** — Send the cleaned audio to the speech-to-text engine Do not enable both Noise Cancellation and Background Noise — they conflict and create audio artifacts. *** ## Knowledge Base Attach knowledge sources that your agent can query during the conversation using Retrieval-Augmented Generation (RAG). When a user asks a question, relevant content is retrieved from the knowledge base and provided to the LLM as context. Knowledge base items are created and managed in the **Knowledge Base** section and then attached to your agent here. → See [Knowledge Base](/agents/knowledge-base/introduction) for full details on creating and managing knowledge items. *** ## MCP Tools Model Context Protocol (MCP) tools attached here are available to all conversation nodes in the flow — any node can invoke them without per-node configuration. Use MCP tools for functions that multiple nodes need (for example, a customer lookup or a business hours check). For actions that only one node needs, use a node-level tool instead. → See [Tools](/agents/tools/introduction) for full details on creating and configuring tools. *** ## Outcome Define how call results are classified for analytics and reporting. ### Configuration ```typescript theme={null} outcomeField: string // Name of the outcome category outcomeResponseShape?: object // Expected response structure (optional) ``` ### Example ```json theme={null} { "outcome": "APPOINTMENT_BOOKED", "details": { "appointment_date": "2024-11-20", "appointment_time": "14:00" } } ``` Outcomes are typically set in End Call nodes, but can also be set via tool calls or webhooks during the conversation. *** ## Phone Number Assign phone numbers to this agent for inbound and outbound calls. **Inbound**: When a customer calls an assigned number, the call routes to this flow agent. **Outbound**: When initiating a call via API, the agent uses one of the assigned numbers as caller ID. All assigned numbers use the same flow configuration. To use different flows for different numbers, create separate agents. *** ## Call Settings Configure timing and behavior defaults for all calls. | Setting | Range | Default | Description | | ----------------------------- | ------------------------------- | ------- | ----------------------------------------------------------------------------------- | | Wait For User To Speak First | Never / Always / Outbound Calls | Never | Whether the agent waits for the user to speak before responding | | Agentic RAG | On / Off | Off | Agent decides when to search the knowledge base. Adds latency but improves accuracy | | User Gender Detection | On / Off | Off | Detects user gender for appropriate speech form (useful for Arabic) | | Smart Call End | On / Off | Off | Ends call gracefully when user asks to wrap up. Has an optional custom prompt | | Language/Dialect Switcher | On / Off | Off | Switches language or dialect instantly when the user requests | | Speaker Identification (Beta) | On / Off | Off | Identify and distinguish different speakers on the call | | Interrupt | On / Off | On | Whether the user can interrupt the agent while speaking | | Ambient Sound | On / Off | Off | Enable ambient background sound | | Thinking Voice | On / Off | Off | Play thinking/processing sound between responses | | Response Delay | 100–1500ms | 400ms | Delay before agent responds | | User Inactivity Timeout | 5–60s | 15s | Time before user is considered inactive | | Max Call Duration | 30s – 1 hour | 5 min | Maximum allowed call length | | Minimum Interruption Duration | 0.2–1.5s | 0.5s | Minimum speech length to count as an interruption | | VAD Activation Threshold | 0.2–0.9 | 0.5 | Voice activity detection sensitivity | → See [Call Behavior Settings](../single-prompt/call-behavior) for full details on each setting. *** ## Webhook Send call events to an external HTTP endpoint. ### Configuration ```typescript theme={null} webhookUrl: string | null webhookAuth: { authKey: 'noAuth' | 'bearer' authSecret?: string } ``` The webhook endpoint must respond within 5 seconds. Return 200 OK quickly and process the payload asynchronously. → See [Webhooks](/agents/webhooks/introduction) for event types, payload structure, and authentication details. *** ## Next Steps Learn about all available node types Control how conversations move between nodes Pass data between nodes and into prompts Tips for building reliable flow agents # Change Agent Settings Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/change-agent-settings-node Override agent settings mid-flow — voice, call behavior, system prompt, and more ## Overview Change Agent Settings nodes override global agent settings from a specific point in the flow. Any setting you override applies from that node forward until another Change Agent Settings node overrides it again or the call ends. **Key characteristic:** No conversation, no user interaction. The node applies setting overrides and immediately advances to the next node. ## When to Use Use Change Agent Settings nodes to: * **Switch voice** mid-conversation (e.g., different voice for different departments) * **Change language** — switch STT model or voice for multilingual flows * **Adjust call behavior** — enable/disable interruptions for critical messages * **Swap system prompt** — different persona or instructions for different flow sections * **Modify response timing** — faster or slower responses based on context *** ## Core Configuration ```typescript theme={null} { type: "change_agent_settings", label?: string, description?: string, // Settings to override settingsOverrides: { // System Prompt systemInstructions?: string, // Voice Settings voiceId?: string, expressiveness?: number, // 0.0–2.0 preferredSttModel?: "Hamsa-STT-S2" | "Hamsa-STT-S3-beta" | "Hamsa-STT-English", voiceDictionaryIds?: string[], // Call Settings interrupt?: boolean, responseDelay?: number, // 100–1500ms userInactivityTimeout?: number, // 5–60s minInterruptionDuration?: number, // 0.2–1.5s vadActivationThreshold?: number, // 0.2–0.9 }, // Transition (automatic — cannot be modified) transitions: Transition[] } ``` Only toggle settings you want to override. Disabled settings inherit from global defaults or upstream Change Agent Settings nodes. *** ## Overridable Settings The form is organized into three collapsible sections. Each section shows a badge with the number of active overrides. ### System Prompt Override the system prompt for all conversation nodes after this point. ```yaml theme={null} Change Agent Settings: Switch_To_Sales_Persona overrides: systemInstructions: | You are a sales specialist for Acme Corp. Focus on understanding the customer's needs and recommending solutions. Be enthusiastic but not pushy. ``` ### Voice Settings Change the voice, expressiveness, STT model, or pronunciation dictionaries. ```yaml theme={null} Change Agent Settings: Switch_Voice overrides: voiceId: "arabic-female-voice-id" expressiveness: 1.5 preferredSttModel: "Hamsa-STT-S2" ``` ### Call Settings Adjust call behavior — interruption handling, response timing, and VAD sensitivity. ```yaml theme={null} Change Agent Settings: Disable_Interruptions overrides: interrupt: false responseDelay: 200 ``` *** ## How Overrides Work ### Inheritance Chain Settings flow through the chain: **Global Settings → Change Agent Settings nodes (in flow order)** If multiple Change Agent Settings nodes exist in a path, each one only overrides the specific settings it defines. All other settings continue to inherit from upstream. ``` Global: voice=A, interrupt=true, delay=400ms → Change Settings Node 1: voice=B (effective: voice=B, interrupt=true, delay=400ms) → Change Settings Node 2: interrupt=false (effective: voice=B, interrupt=false, delay=400ms) ``` ### Reset Button Each section has a reset button that removes all overrides in that section, reverting those settings to their inherited values. *** ## Use Cases & Examples ### Example 1: Language Switch Switch voice and STT model when routing to a different language. ```yaml theme={null} Router Node: Language_Router transitions: - Equation: {{preferred_language}} == "ar" → Arabic_Settings - Always → English_Settings Change Agent Settings: Arabic_Settings overrides: voiceId: "arabic-voice-id" preferredSttModel: "Hamsa-STT-S2" → Arabic_Conversation Change Agent Settings: English_Settings overrides: voiceId: "english-voice-id" preferredSttModel: "Hamsa-STT-English" → English_Conversation ``` ### Example 2: Disable Interruptions for Important Messages ```yaml theme={null} Change Agent Settings: No_Interrupts overrides: interrupt: false → Important_Announcement Conversation Node: Important_Announcement message: "Please listen carefully to the following terms and conditions..." → Re_Enable_Interrupts Change Agent Settings: Re_Enable_Interrupts overrides: interrupt: true → Continue_Flow ``` ### Example 3: Department-Specific Persona ```yaml theme={null} Change Agent Settings: Sales_Mode overrides: systemInstructions: | You are a sales specialist. Focus on understanding needs and recommending the right product package. voiceId: "energetic-voice-id" expressiveness: 1.8 → Sales_Conversation ``` *** ## Static Variables Change Agent Settings nodes also support setting static variables (same as the Set Local Variables node). Use the Variables section in the form to define variables alongside setting overrides. *** ## Transitions Change Agent Settings nodes use an **automatic transition** — they apply overrides and immediately advance to the next connected node. You cannot add, remove, or edit transitions on this node type. *** ## Flow Examples ### Pattern: Voice Switch by Department ```mermaid theme={null} graph TD Router{Router:
Department} SalesSettings[Change Settings:
Sales Voice] SupportSettings[Change Settings:
Support Voice] Sales[Sales Conversation] Support[Support Conversation] Router -->|"sales"| SalesSettings Router -->|"support"| SupportSettings SalesSettings --> Sales SupportSettings --> Support ``` ### Pattern: Temporary Override ```mermaid theme={null} graph LR Disable[Change Settings:
Disable Interrupts] Message[Conversation:
Important Info] Enable[Change Settings:
Enable Interrupts] Continue[Continue Flow] Disable --> Message --> Enable --> Continue ``` *** ## Next Steps Set variable values without conversation Configure agent-level defaults Have conversations with overridden settings Route before changing settings # Conversation Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/conversation-node Natural dialogue with users - the most commonly used node type ## Overview The conversation node is the most commonly used node type in flow agents. It's designed for having natural conversations with users, where the AI listens, understands, and responds based on its prompt and context. **Key characteristic:** When inside a conversation node, the agent focuses on dialogue without calling tools or performing actions (unless configured otherwise). ## When to Use Use conversation nodes to: * Greet callers and establish rapport * Ask questions and collect information * Provide information or explanations * Handle objections or concerns * Confirm understanding or intent * Give instructions or directions * Conduct surveys or questionnaires ## Core Configuration ### Message Type Choose how the agent's response is generated: #### **Prompt (Dynamic)** The agent generates responses dynamically based on the prompt and conversation context. **Best for:** * Natural conversations * Handling varied user inputs * Adaptive responses * Complex scenarios **Example:** ``` Prompt: "Ask the user for their name and phone number. Be friendly and explain we need this for follow-up." ``` Agent might say: * "Hi! To help you better, could I get your name and phone number?" * "Great! And what's the best number to reach you at?" #### **Static (Fixed Message)** The agent speaks a predetermined message exactly as written. **Best for:** * Consistent greetings * Legal disclaimers * Scripted announcements * Confirmation messages **Example:** ``` Static Message: "Thank you for calling Acme Corp. This call may be recorded for quality assurance." ``` Agent says exactly this, every time. ### Node Prompt The instructions that guide the agent's behavior within this specific node. **Structure your prompt:** ``` ## Objective [What should this node accomplish?] ## Context [What information does the agent have at this point?] ## Instructions [How should the agent behave? What to ask?] ## Constraints [What should the agent NOT do or say?] ## Success Criteria [When is this node's job complete?] ``` Reference available variables with `{{variable_name}}` syntax. Prompts also support full **Jinja2** template syntax — use conditionals, filters, and expressions to build dynamic prompts. See the [Jinja2 Template Designer Documentation](https://jinja.palletsprojects.com/en/stable/templates/) for the full reference. Each node should have a distinct, focused purpose. **Example - Information Gathering Node:** ``` ## Objective Collect the customer's appointment preferences. ## Instructions - Ask what service they're interested in - Ask for their preferred date and time - Confirm availability exists before moving forward - Be friendly and accommoding ## Constraints - Don't book the appointment yet (that's the next node) - Don't ask for payment information ## Use Variables - Reference {{customer_name}} if already collected ``` ## Advanced Features ### Variable Extraction Automatically extract and store data from the conversation into variables. **How to configure:** 1. Enable "Extract Variables" 2. Define variable name(s) to extract 3. Optionally provide extraction instructions **Example:** ``` Variable Name: customer_name Extraction Prompt: "Extract the customer's full name from the conversation" Variable Name: appointment_date Extraction Prompt: "Extract the requested appointment date in YYYY-MM-DD format" ``` **Extracted variables become available to:** * Subsequent nodes in the flow * Tool parameters * Transition conditions * Other prompts using `{{variable_name}}` **[→ Learn More: Variable System](/agents/variables/introduction)** ### DTMF Input Capture Collect sequences of phone keypad digits (account numbers, PINs, confirmation codes). **How to configure:** 1. Enable "DTMF Input Capture" 2. Set variable name (required) 3. Configure completion conditions (optional): * **Digit Limit**: Stop after X digits (1-20) * **Termination Key**: Stop when user presses # or \* * **Timeout**: Stop after X seconds of no input (1-30) **Example - Account Number Collection:** ``` Message: "Please enter your 10-digit account number followed by the pound key" DTMF Settings: - Variable Name: account_number - Digit Limit: 10 - Termination Key: # - Timeout: 15 seconds ``` **Captured variable usage:** ``` Next node prompt: "Thank you! I'm looking up account {{account_number}} now..." Tool parameter: account_id = {{account_number}} ``` **[→ Learn More: DTMF Features](../dtmf)** ## Transitions Conversation nodes support all transition types: ### 1. Natural Language Transitions ``` Condition: "User confirmed they want to book appointment" → Next Node: Book_Appointment ``` ### 2. Structured Equation Transitions ``` Condition: {{user_age}} >= 18 → Next Node: Adult_Workflow ``` ### 3. DTMF Transitions ``` Simple DTMF: Press 1 for Sales → Next Node: Sales_Department ``` **[→ Learn More: Transition Conditions](../transitions)** ## Global Node Configuration Any conversation node can be made **global**, meaning it's accessible from anywhere in the flow. **Global trigger types:** ### Prompt-Based Global Trigger ``` Global Condition: "User wants to speak to a human operator" ``` Accessible from any node when user expresses this intent. ### DTMF Global Trigger ``` Global DTMF Key: 0 ``` Accessible from any node when user presses 0. **Common global conversation nodes:** * "Speak to operator" (DTMF 0 or natural language) * "Repeat main menu" (DTMF 9) * "Emergency support" (natural language or DTMF \*) * "Return to start" (DTMF #) **[→ Learn More: Global Nodes](../global-nodes)** ## Examples ### Example 1: Greeting Node (Static) ```yaml theme={null} Type: Conversation Node Message Type: Static Message: "Thank you for calling Acme Corporation. How can I help you today?" Skip Response: OFF Transitions: - Natural Language: "User states their reason for calling" → Route_Call ``` ### Example 2: Information Gathering (Dynamic) ```yaml theme={null} Type: Conversation Node Message Type: Prompt Prompt: | ## Objective Collect customer name, email, and phone number ## Instructions - Ask for full name first - Then ask for email address - Finally ask for phone number - Confirm you have the correct information - Be friendly and patient ## Validation - Ensure email contains @ - Ensure phone is 10 digits - Repeat back for confirmation Variable Extraction: - customer_name: "Extract full name" - customer_email: "Extract email address" - customer_phone: "Extract 10-digit phone number" Transitions: - Natural Language: "All information collected and confirmed" → Next_Step - Natural Language: "User refused to provide info" → Objection_Handler ``` ### Example 3: Account Number Entry (DTMF) ```yaml theme={null} Type: Conversation Node Message Type: Static Message: 'Please enter your 8-digit account number followed by the pound key' DTMF Input Capture: Enabled: true Variable Name: account_number Digit Limit: 8 Termination Key: # Timeout: 20 seconds Skip Response: OFF Transitions: - Always → Verify_Account (Tool Node) ``` ### Example 4: Pre-Transfer Announcement (Skip Response) ```yaml theme={null} Type: Conversation Node Message Type: Static Message: 'Perfect! Let me transfer you to our billing specialist. Please hold.' Skip Response: ON Transitions: - Always → Transfer_To_Billing ``` ## Troubleshooting ### Agent not following prompt instructions **Solution:** * Simplify prompt, be more explicit * Add fine-tune examples * Use stronger LLM model * Split into multiple smaller nodes ### Variable extraction not working **Solution:** * Make variable names more descriptive * Provide clearer extraction instructions * Ensure conversation contains the data * Check variable reference syntax `{{var_name}}` ### DTMF not capturing correctly **Solution:** * Verify digit limit is appropriate * Test with different phones/providers * Increase timeout for slower users * Ensure variable name is valid (snake\_case) ### Transitions not triggering **Solution:** * Review transition conditions carefully * Test with actual user phrases * Check variable availability * Ensure equation syntax is correct * Add fallback "always" transition ## Next Steps * **[Tool Node](./tool-node)** - Execute functions and API calls * **[Router Node](./router-node)** - Pure logic branching * **[Transfer Nodes](./transfer-call-node)** - Call and agent transfers * **[Transition Conditions](../transitions)** - Control conversation flow * **[Variable System](/agents/variables/introduction)** - Pass data between nodes *** **Questions?** Check out **[Debugging Guide](../debugging)** for troubleshooting tips. # End Call Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/end-call-node Gracefully terminate calls with customizable farewell messages ## Overview End call nodes terminate the conversation and disconnect the call. They provide a clean, graceful way to end calls with optional farewell messages and tracking of call completion reasons. Every flow should have clear paths to end call nodes to avoid leaving callers hanging. **Key characteristic:** End call nodes are terminal nodes—the flow stops here, and the call disconnects. ## When to Use Use end call nodes to: * **Successful completion** - Caller's needs were met * **User-requested termination** - Caller asks to end call * **Error scenarios** - Technical issues requiring call termination * **Timeout handling** - No user input for extended period * **After transfers** - Clean up after transferring to external number * **Opt-out handling** - User declines service or opts out * **Survey completion** - End of feedback collection * **Appointment confirmation** - After successful booking **Every flow should:** * Have at least one end call node * Provide clear paths to termination * Handle both success and failure scenarios * Give appropriate farewell messages *** ## Core Configuration ```typescript theme={null} { type: "end_call", label?: string, description?: string, // Final message (optional) finalMessage?: string, messageType: "static" | "prompt", // Default: "static" // No transitions (terminal node) transitions: [] // Always empty } ``` End call nodes are terminal nodes—they have no transitions. Once reached, the flow ends and the call disconnects. *** ## Final Message ### Static Message Exact, predetermined farewell message spoken every time. ```yaml theme={null} End Call Node: Call_Complete Final Message: message: "Thank you for calling Acme Corporation. Have a great day!" messageType: static ``` **Use static when:** * Consistent, professional farewell * Brand-specific closing * Legal disclaimers needed * Simple, universal goodbye ### Prompt-Based Message AI generates contextual farewell based on conversation. ```yaml theme={null} End Call Node: Call_Complete Final Message: message: "Thank the caller warmly, reference their specific issue, and wish them a great day." messageType: prompt ``` **AI might say:** * "Thank you for calling about your account update, `{{customer_name}}`. Have a wonderful day!" * "I'm glad I could help with your question. Thanks for calling, and take care!" **Use prompt when:** * Want personalized, contextual farewell * Reference specific conversation topics * Natural, conversational ending * Dynamic based on outcome ### Message with Variables Use extracted variables in farewell. ```yaml theme={null} End Call Node: Appointment_Confirmed Final Message: message: "Perfect! Your appointment is confirmed for {{appointment_date}} at {{appointment_time}}. We'll send a reminder to {{customer_email}}. Thank you, {{customer_name}}!" messageType: static ``` ### Silent Termination (No Message) End call immediately without farewell. ```yaml theme={null} End Call Node: Silent_End # No finalMessage - immediate disconnect ``` **Use when:** * After transfer (new system handles goodbye) * Error requires immediate termination * User already said goodbye * Abrupt ending is appropriate *** ## Use Cases & Examples ### Example 1: Successful Completion **Scenario:** User's question answered, end positively. ```yaml theme={null} Conversation Node: Answer_Question message: "I hope that answers your question about our pricing." transitions: - Natural Language: "User is satisfied" → Call_Complete - Natural Language: "User has more questions" → Continue_Conversation End Call Node: Call_Complete Final Message: message: "Thank you for calling Acme Corp. If you have any other questions, feel free to call back. Have a wonderful day!" messageType: static ``` ### Example 2: After Appointment Booking **Scenario:** Appointment booked, confirm and end. ```yaml theme={null} Tool Node: Book_Appointment outputMapping: appointment_date: $.date appointment_time: $.time confirmation_number: $.confirmation_id transitions: - Always → Appointment_Confirmed End Call Node: Appointment_Confirmed Final Message: message: "Your appointment is confirmed for {{appointment_date}} at {{appointment_time}}. Your confirmation number is {{confirmation_number}}. We'll send a reminder email. Thank you, and see you then!" messageType: static ``` ### Example 3: User Requested End **Scenario:** User says they're done. ```yaml theme={null} Conversation Node: Anything_Else message: "Is there anything else I can help you with today?" transitions: - Natural Language: "User says no or goodbye" → User_Goodbye - Natural Language: "User has more questions" → Continue_Support End Call Node: User_Goodbye Final Message: message: "Thank you for calling. Have a great day!" messageType: static ``` ### Example 4: Error Termination **Scenario:** Critical API failure, can't continue. ```yaml theme={null} Tool Node: Critical_Database_Lookup onErrorBehavior: fail transitions: - Always → Database_Error_End End Call Node: Database_Error_End Final Message: message: "I'm experiencing technical difficulties accessing our system. Please try calling back in a few minutes, or visit our website. We apologize for the inconvenience." messageType: static ``` ### Example 5: Timeout Scenario **Scenario:** User inactive for 60 seconds. ```yaml theme={null} Router Node: Check_User_Active # System monitors inactivity transitions: - Equation: {{seconds_since_input}} > 60 → Timeout_Warning - Always → Continue_Conversation Conversation Node: Timeout_Warning message: "Are you still there? Let me know if you need more time." skipResponse: false transitions: - Natural Language: "User responds" → Resume_Conversation - Equation: {{seconds_since_input}} > 30 → Timeout_End End Call Node: Timeout_End Final Message: message: "I haven't heard from you. Please call back when you're ready. Goodbye!" messageType: static ``` ### Example 6: After Transfer **Scenario:** Transfer to human, then end AI call. ```yaml theme={null} Transfer Call Node: Transfer_To_Human phoneNumber: +18005551234 transferType: warm transferMessage: "I'm transferring you to a specialist now." transitions: - Always → End_After_Transfer End Call Node: End_After_Transfer # No final message - transfer system handles it ``` ### Example 7: Opt-Out Handling **Scenario:** User opts out of service. ```yaml theme={null} Conversation Node: Opt_Out_Confirmation message: "I understand you'd like to opt out. I've processed that request." transitions: - Always → Opt_Out_Complete End Call Node: Opt_Out_Complete Final Message: message: "Your opt-out request has been processed. You won't receive further calls. Thank you." messageType: static ``` ### Example 8: Survey Completion **Scenario:** Customer satisfaction survey finished. ```yaml theme={null} Conversation Node: Final_Question message: "On a scale of 1-10, how satisfied are you with our service?" Extract Variables: - satisfaction_score: "Extract rating 1-10" transitions: - Always → Survey_Complete Tool Node: Submit_Survey tool: Save_Survey_Results parameters: score: {{satisfaction_score}} transitions: - Always → Thank_You_End End Call Node: Thank_You_End Final Message: message: "Thank you for your feedback! It helps us improve our service. Have a great day!" messageType: static ``` ### Example 9: Multiple End Paths **Scenario:** Different endings for different outcomes. ```yaml theme={null} Router Node: Outcome_Router transitions: - Equation: {{issue_resolved}} == true → Success_End - Equation: {{transferred_to_human}} == true → Transfer_End - Equation: {{user_frustrated}} == true → Apologetic_End - Always → Standard_End End Call Node: Success_End finalMessage: "I'm glad I could resolve your issue. Thank you for calling!" End Call Node: Transfer_End finalMessage: "You've been transferred. Have a great day!" End Call Node: Apologetic_End finalMessage: "I apologize we couldn't resolve this to your satisfaction. Please contact our support team for further assistance. Thank you." End Call Node: Standard_End finalMessage: "Thank you for calling. Goodbye!" ``` ### Example 10: Contextual Personalized Ending **Scenario:** Reference conversation details in goodbye. ```yaml theme={null} End Call Node: Personalized_Goodbye Final Message: message: "Thank you, {{customer_name}}! Your {{order_type}} order for {{product_name}} will arrive on {{delivery_date}}. We appreciate your business!" messageType: static ``` *** ## Flow Examples ### Example Flow 1: Simple Support ```mermaid theme={null} graph TD Start[Start: Greeting] Support[Conversation: Support] Resolved{Router: Resolved?} End[End: Success] Transfer[Transfer: Human] Start --> Support Support --> Resolved Resolved -->|"yes"| End Resolved -->|"no"| Transfer ``` ### Example Flow 2: Error Handling ```mermaid theme={null} graph TD Start[Start] Tool[Tool: API Call] Success{Router: Success?} Complete[End: Completed] Error[End: Error] Start --> Tool Tool --> Success Success -->|"success"| Complete Success -->|"error"| Error ``` ### Example Flow 3: User Choice ```mermaid theme={null} graph TD Menu[Conversation: How can I help?] Continue{Router: Continue?} More[More Questions] Goodbye[End: User Requested] Menu --> Continue Continue -->|"more questions"| More Continue -->|"done"| Goodbye More --> Menu ``` *** ## Troubleshooting ### Issue: Calls ending abruptly **Possible causes:** * No final message configured * Message generation failing * Transition directly to end without conversation **Solution:** 1. Add final message 2. Use static message if prompt fails 3. Add transition node before end ### Issue: Users confused at end **Possible causes:** * Unclear final message * No confirmation of actions taken * Missing next steps **Solution:** 1. Clarify what happened in final message 2. Confirm important details 3. Provide next steps or follow-up info ### Issue: No path to end call **Possible causes:** * Flow has no end nodes * Transitions don't lead to end * Circular conversation loop **Solution:** 1. Add end call nodes 2. Review all transition paths 3. Ensure every path can reach an end *** ## Schema Reference ```typescript theme={null} { type: "end_call", label?: string, description?: string, // Final message (optional) finalMessage?: string, messageType: "static" | "prompt", // Default: "static" // Transitions (always empty - terminal node) transitions: [], // Position position: { x: number, y: number } } ``` *** ## Common Patterns ### Pattern 1: Confirmation + End ```yaml theme={null} Conversation Node: Confirm_Action message: "I've completed {{action}}. Is there anything else?" transitions: - Natural Language: "no" → End_Complete - Natural Language: "yes" → Continue_Support End Call Node: End_Complete finalMessage: "Great! Thank you for calling." ``` ### Pattern 2: Multi-Outcome Routing ```yaml theme={null} Router Node: Determine_Outcome transitions: - Equation: {{success}} == true → Success_End - Equation: {{error}} == true → Error_End - Always → Standard_End ``` ### Pattern 3: Pre-End Feedback ```yaml theme={null} Conversation Node: Get_Feedback message: "Before you go, how was your experience today? Good, okay, or bad?" extractVariables: - feedback: "Extract sentiment" transitions: - Always → Thank_And_End End Call Node: Thank_And_End finalMessage: "Thank you for your feedback! Have a great day." ``` *** ## Next Steps Begin flows that end gracefully Lead to satisfying conclusions Route to appropriate endings Transfer before ending Path to end call nodes Build better flows # Node Types Overview Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/overview Complete guide to all Flow Agent node types and when to use each ## Overview Flow agents use nodes as building blocks to create sophisticated conversation workflows. Each node type serves a specific purpose, and understanding when to use each type is key to building effective flows. ## All Node Types at a Glance | Node Type | Primary Purpose | Key Features | Common Use Cases | | ------------------------- | ------------------------- | --------------------------------- | -------------------------------------- | | **Start Node** | Flow entry point | Dual mode: conversation or tool | Initial greeting, pre-fetch data | | **Conversation Node** | Natural dialogue | Variable extraction, DTMF capture | Collect info, ask questions, explain | | **Tool Node** | Execute tool templates | Parameter mapping, error handling | API calls, database lookups | | **Web Tool Node** | Client-side browser tools | Runs in user's browser via SDK | UI navigation, page interactions | | **Router Node** | Conditional branching | Pure logic, no conversation | Route based on data, decision trees | | **Transfer Call Node** | Phone transfer | Warm/cold transfer to number | Escalate to human, department routing | | **Transfer Agent Node** | Agent handoff | Switch to different Hamsa agent | Specialist routing, language switching | | **End Call Node** | Terminate call | Final message, graceful exit | Completion, timeout, error handling | | **Set Local Variables** | Set variable values | Assign static or computed values | Initialize data, transform values | | **Change Agent Settings** | Modify agent config | Change settings mid-conversation | Switch voice, adjust behavior | *** ## Start Node **Purpose:** Entry point for every flow. The first node executed when a call begins. ### Two Operating Modes #### Conversation Mode (Default) Greets the caller and initiates dialogue. ```yaml theme={null} Start Node (Conversation): message: "Thank you for calling Acme Corp. How can I help you today?" messageType: prompt Transitions: - Natural Language: "User needs sales" → Sales_Department - Natural Language: "User needs support" → Support_Department - DTMF: key=1 → Sales_Department - DTMF: key=2 → Support_Department ``` #### Tool Mode Executes a tool before any conversation, useful for pre-fetching caller data. ```yaml theme={null} Start Node (Tool): subType: tool tool: Lookup_Caller_Info parameters: phone_number: { { caller_id } } Transitions: - Always → Personalized_Greeting ``` **When to use:** * Conversation mode: Standard flows that start with a greeting * Tool mode: Pre-fetch customer data, check account status, log call start **[→ Full Documentation: Start Node](./start-node)** *** ## Conversation Node **Purpose:** The workhorse of flow agents. Used for natural dialogue with users. ### Key Capabilities * **Dynamic or static messages:** AI-generated responses or fixed scripts * **Variable extraction:** Automatically capture data from conversation * **DTMF input capture:** Collect account numbers, PINs, phone numbers * **Skip response mode:** Speak without waiting for user input * **Block interruptions:** Prevent users from interrupting critical messages **Example - Information Gathering:** ```yaml theme={null} Conversation Node: Collect_Contact_Info messageType: prompt message: | Ask the user for their name, email, and phone number. Be friendly and explain we need this for follow-up. Variable Extraction: - customer_name: "Extract full name" - customer_email: "Extract email address" - customer_phone: "Extract 10-digit phone" Transitions: - Natural Language: "All info collected" → Next_Step - Natural Language: "User declined" → Objection_Handler ``` **When to use:** * Greeting callers * Asking questions and collecting information * Providing explanations or instructions * Handling objections * Conducting surveys * Confirming understanding **[→ Full Documentation: Conversation Node](./conversation-node)** *** ## Tool Node **Purpose:** Execute reusable tool templates (API Request tools, MCP tools, Function tools). ### Key Features * **Parameter mapping:** Map variables to tool inputs * **Error handling:** Continue, retry, or fail on errors * **Custom responses:** Override default tool responses * **Output mapping:** Extract data from responses into variables * **Processing messages:** Display messages while tool executes * **Timeout configuration:** Set max execution time **Example - Customer Lookup:** ```yaml theme={null} Tool Node: Lookup_Customer tool: CRM_Customer_Lookup Parameters: phone_number: {{caller_phone}} include_orders: true Output Mapping: customer_id: $.data.id customer_name: $.data.full_name account_status: $.data.status Error Handling: onErrorBehavior: continue errorMessage: "I'm having trouble accessing your account right now." Processing Message: message: "Let me look up your account information..." messageType: static Transitions: - Equation: {{account_status}} == "active" → Active_Flow - Equation: {{account_status}} == "suspended" → Suspended_Flow - Always → Default_Flow ``` **When to use:** * Database lookups * API integrations * Check availability, status, or inventory * Submit forms or create records * Retrieve customer data * Process payments * Send notifications **[→ Full Documentation: Tool Node](./tool-node)** *** ## Web Tool Node **Purpose:** Make one-off HTTP requests without creating a reusable tool template. ### Key Features * **Inline configuration:** Define HTTP request directly in the node * **No template needed:** Perfect for single-use API calls * **Same capabilities as Tool Node:** Parameters, error handling, output mapping * **Rapid prototyping:** Test integrations before creating templates **Example - Weather API (One-off):** ```yaml theme={null} Web Tool Node: Check_Weather method: GET url: https://api.weather.com/v1/current Query Parameters: city: {{user_city}} units: imperial Headers: X-API-Key: {{env.WEATHER_API_KEY}} Output Mapping: temperature: $.current.temp conditions: $.current.conditions Custom Response: overrideResponse: true customResponse: "It's currently {{temperature}} degrees with {{conditions}}." Transitions: - Always → Continue_Conversation ``` **When to use:** * Quick one-off integrations * Prototyping before creating tool templates * Flow-specific API calls unlikely to be reused * Testing API endpoints * Simple GET requests **When NOT to use:** * Tools needed across multiple agents (create a template instead) * Complex error handling requirements * Tools requiring extensive documentation **[→ Full Documentation: Web Tool Node](./web-tool-node)** *** ## Router Node **Purpose:** Pure conditional routing based on variables and equations—no conversation. ### Key Features * **No conversation:** Instantly evaluates and transitions * **Multiple conditions:** Complex decision trees with AND/OR logic * **Variable-based routing:** Branch on extracted data * **High performance:** Fast evaluation, no LLM calls **Example - Lead Qualification Router:** ```yaml theme={null} Router Node: Qualify_Lead label: "Route based on budget and decision maker" Transitions: - Structured Equation (Priority 1): logic: all conditions: - {{budget_range}} >= 5000 - {{is_decision_maker}} == true - {{timeline}} == "immediate" → High_Priority_Sales - Structured Equation (Priority 2): logic: all conditions: - {{budget_range}} >= 1000 - {{budget_range}} < 5000 → Medium_Priority_Nurture - Structured Equation (Priority 3): logic: any conditions: - {{budget_range}} < 1000 - {{is_decision_maker}} == false → Low_Priority_Followup - Always → Default_Path ``` **When to use:** * Route based on extracted variables * Implement business logic * Create decision trees * A/B test different conversation paths * Route by time of day, caller type, account status * Split flows based on data (not conversation content) **When NOT to use:** * When conversation is needed to determine next step (use conversation node instead) * Simple single-condition routing (use conversation node with natural language transition) **[→ Full Documentation: Router Node](./router-node)** *** ## Transfer Call Node **Purpose:** Transfer the phone call to another phone number. ### Key Features * **Warm transfer:** Announce transfer before connecting * **Cold transfer:** Immediate transfer without announcement * **Transfer message:** Customizable pre-transfer message * **Phone number validation:** E.164 format required * **Timeout configuration:** Set max wait time **Example - Transfer to Sales Team:** ```yaml theme={null} Transfer Call Node: Transfer_To_Sales phoneNumber: +18005551234 transferType: warm Transfer Message: message: "Let me connect you with our sales team who can better assist you." messageType: static Timeout: 30000 # 30 seconds ``` **Example - Emergency Transfer (Global):** ```yaml theme={null} Transfer Call Node: Emergency_Transfer isGlobal: true globalConditionType: dtmf globalDtmfKey: 0 phoneNumber: +18005550911 transferType: cold Transfer Message: message: "Transferring you to a specialist now." ``` **When to use:** * Escalate to human agents * Department-specific routing * After-hours transfer to answering service * Emergency or high-priority scenarios * Specialized support requiring human interaction **When NOT to use:** * Transferring to another Hamsa agent (use Transfer Agent Node instead for better experience) * When conversation can continue with AI **[→ Full Documentation: Transfer Call Node](./transfer-call-node)** *** ## Transfer Agent Node **Purpose:** Transfer to another Hamsa agent while maintaining conversation context. ### Key Features * **Lower latency:** No phone transfer needed * **Context preservation:** Full conversation history passed * **Better reliability:** No call quality issues * **No repeated questions:** New agent has full context * **Seamless experience:** User doesn't realize they switched agents **Example - Language Switch:** ```yaml theme={null} Transfer Agent Node: Switch_To_Spanish agentId: "spanish-support-agent-id" Transfer Message: message: "Let me connect you with our Spanish-speaking representative." messageType: static Timeout: 30000 ``` **Example - Specialist Routing:** ```yaml theme={null} Conversation Node: Identify_Need message: "Are you calling about technical support or billing?" Transitions: - Natural Language: "Technical issue" → Transfer_To_Tech - Natural Language: "Billing question" → Transfer_To_Billing Transfer Agent Node: Transfer_To_Tech agentId: "technical-support-agent" transferMessage: "Let me connect you with our technical specialist." Transfer Agent Node: Transfer_To_Billing agentId: "billing-support-agent" transferMessage: "Let me connect you with our billing department." ``` **When to use:** * Route to specialized agents (tech support, billing, sales) * Language switching (English → Spanish → Mandarin) * Complexity escalation (simple → advanced agent) * Department routing within your AI system * Workflow hand-offs (qualification → closing) **Advantages over Transfer Call Node:** * **Faster:** No phone system involved * **Smarter:** New agent has full context * **Cheaper:** No telephony transfer costs * **Better UX:** No hold music or reconnection **[→ Full Documentation: Transfer Agent Node](./transfer-agent-node)** *** ## End Call Node **Purpose:** Gracefully terminate the conversation. ### Key Features * **Final message:** Optional goodbye message * **Call reason tracking:** Mark why call ended * **Static or dynamic message:** Fixed script or AI-generated * **Clean termination:** Proper call cleanup **Example - Successful Completion:** ```yaml theme={null} End Call Node: Call_Complete reason: completed Final Message: message: "Thank you for calling Acme Corp. Have a great day!" messageType: static ``` **Example - Timeout Handling:** ```yaml theme={null} End Call Node: Timeout_End reason: timeout Final Message: message: "I haven't heard from you in a while. Please call back when you're ready. Goodbye!" messageType: static ``` **Example - Error Termination:** ```yaml theme={null} End Call Node: Error_End reason: error Final Message: message: "I'm experiencing technical difficulties. Please try calling back in a few minutes." messageType: static ``` **When to use:** * Successfully completed conversations * User requested to end call * Timeout scenarios (no user input) * Error scenarios requiring termination * After transfer (to ensure original call ends) **Reason Types:** * `completed`: Normal completion * `user_requested`: User asked to end call * `error`: System error occurred * `timeout`: User inactive too long **[→ Full Documentation: End Call Node](./end-call-node)** *** ## Node Selection Guide ### Decision Tree: Which Node Should I Use? ``` Need to start the flow? → START NODE Need to have a conversation? → CONVERSATION NODE Need to call an API or execute a tool? ├─ Using existing tool template? │ → TOOL NODE └─ One-off HTTP request? → WEB TOOL NODE Need to route based on data without conversation? → ROUTER NODE Need to transfer the call? ├─ To phone number? │ → TRANSFER CALL NODE └─ To another Hamsa agent? → TRANSFER AGENT NODE Need to end the call? → END CALL NODE ``` *** ## Common Node Combinations ### Pattern 1: Conversation → Tool → Conversation Collect information, call API, discuss results. ``` [Conversation: Ask for account number] → [Tool: Lookup account] → [Conversation: Discuss account details] ``` ### Pattern 2: Tool → Router → Multiple Paths Fetch data, route based on results. ``` [Tool: Check inventory] → [Router: In stock?] ├─ Yes → [Conversation: Proceed with order] └─ No → [Conversation: Suggest alternatives] ``` ### Pattern 3: Conversation → Router → Transfer/End Qualify, route to appropriate endpoint. ``` [Conversation: Qualification questions] → [Router: Decision tree] ├─ High priority → [Transfer Agent: Sales specialist] ├─ Medium priority → [Conversation: Self-service] └─ Low priority → [End Call: Follow-up email] ``` ### Pattern 4: Start (Tool) → Conversation Pre-fetch data, personalized greeting. ``` [Start (Tool mode): Lookup caller] → [Conversation: "Welcome back, {{customer_name}}!"] ``` *** ## Next Steps **Explore individual node types in detail:** Flow entry point with conversation or tool mode Natural dialogue with variable extraction Execute reusable tool templates Client-side browser tools via SDK Conditional routing based on logic Transfer to phone number Switch to another Hamsa agent Gracefully terminate calls Set variable values without conversation Override agent settings mid-flow **Learn related concepts:** Control flow between nodes Pass data between nodes Keypad interactions and input capture Accessible from anywhere in flow # Router Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/router-node Conditional routing based on variables and equations without conversation ## Overview Router nodes perform pure conditional logic routing without having any conversation. They instantly evaluate conditions based on variables and data, then transition to the appropriate next node. Think of router nodes as the "if/else" or "switch/case" statements of your flow. **Key characteristic:** Router nodes execute instantly—no conversation, no waiting for user input, just logic evaluation and immediate transition. ## When to Use Use router nodes to: * **Route based on extracted data:** Direct flow based on account status, tier, location * **Implement business logic:** Different paths for different customer segments * **Create decision trees:** Multi-branch routing based on multiple conditions * **Handle tool responses:** Route based on API results * **A/B test flows:** Split traffic between different conversation paths * **Time-based routing:** Different flows for business hours vs after hours * **Priority routing:** High-value leads to different paths **Use Router Node when:** * Decision is based on variables/data, not conversation * You need multiple conditional branches * Logic is deterministic (not LLM-based) * Instant routing without user interaction **Use Conversation Node instead when:** * Need to ask questions to determine next step * Decision requires conversation context * Want natural language understanding *** ## Core Configuration Router nodes have minimal configuration—they're pure routing logic. ```typescript theme={null} { type: "router", label?: string, description?: string, // Router nodes only have transitions // No conversation, no tools, no settings transitions: Transition[] // At least one required } ``` The power of router nodes is entirely in their transitions. All logic is defined through transition conditions. *** ## Transition Types Router nodes support structured equation and always transitions. Natural language transitions are not typically used (no conversation to evaluate). ### Structured Equation Transitions Define logical conditions using variables and operators. #### Simple Condition ```yaml theme={null} Router Node: Check_Account_Status transitions: - Equation: {{account_status}} == "active" → Active_Flow - Equation: {{account_status}} == "suspended" → Suspended_Flow - Equation: {{account_status}} == "closed" → Closed_Flow - Always → Unknown_Status_Flow ``` #### Multiple Conditions (AND Logic) All conditions must be true. ```yaml theme={null} Router Node: Qualify_Lead transitions: - Structured Equation (logic: all): - {{budget}} >= 5000 - {{is_decision_maker}} == true - {{timeline}} == "immediate" → High_Priority_Sales - Structured Equation (logic: all): - {{budget}} >= 1000 - {{budget}} < 5000 → Medium_Priority - Always → Low_Priority ``` #### Multiple Conditions (OR Logic) Any condition can be true. ```yaml theme={null} Router Node: Emergency_Check transitions: - Structured Equation (logic: any): - {{urgency_level}} == "critical" - {{is_emergency}} == true - {{priority_customer}} == true → Immediate_Escalation - Always → Standard_Process ``` ### Always Transition Fallback when no other conditions match. ```yaml theme={null} Router Node: Category_Router transitions: - Equation: {{category}} == "sales" → Sales_Flow - Equation: {{category}} == "support" → Support_Flow - Equation: {{category}} == "billing" → Billing_Flow - Always → General_Flow # Catch-all for unknown categories ``` Always include an "always" transition as a fallback. Router nodes without a matching transition will cause flow errors. *** ## Operators Use these operators in equation conditions: | Operator | Description | Example | | -------------- | ---------------------- | --------------------------------- | | `==` | Equals | `{{status}} == "active"` | | `!=` | Not equals | `{{status}} != "suspended"` | | `>` | Greater than | `{{age}} > 18` | | `<` | Less than | `{{balance}} < 0` | | `>=` | Greater than or equal | `{{score}} >= 80` | | `<=` | Less than or equal | `{{items}} <= 5` | | `contains` | String contains | `{{email}} contains "@gmail.com"` | | `not_contains` | String doesn't contain | `{{phone}} not_contains "+1"` | | `exists` | Variable exists | `{{customer_id}} exists` | | `not_exists` | Variable doesn't exist | `{{customer_id}} not_exists` | | `regex` | Matches regex pattern | `{{phone}} regex "^\+1\d{10}$"` | ### Comparison Examples **String comparison:** ```yaml theme={null} {{customer_tier}} == "premium" {{location}} == "USA" {{status}} != "inactive" ``` **Numeric comparison:** ```yaml theme={null} {{order_total}} >= 100 {{quantity}} > 0 {{discount_percentage}} <= 20 ``` **Boolean comparison:** ```yaml theme={null} {{is_verified}} == true {{has_subscription}} == false ``` **Contains:** ```yaml theme={null} {{email}} contains "@company.com" {{full_name}} contains "Smith" {{phone}} not_contains "+1" ``` *** ## Use Cases & Examples ### Example 1: Account Status Routing **Scenario:** Different flows for different account statuses. ```yaml theme={null} # Previous node extracts account_status Tool Node: Lookup_Account outputMapping: account_status: $.status transitions: - Always → Status_Router Router Node: Status_Router label: "Route by account status" transitions: - Equation: {{account_status}} == "active" → Active_Account_Flow - Equation: {{account_status}} == "suspended" → Reactivation_Flow - Equation: {{account_status}} == "trial" → Trial_Extension_Flow - Equation: {{account_status}} == "cancelled" → Win_Back_Flow - Always → New_Customer_Flow ``` ### Example 2: Budget-Based Lead Qualification **Scenario:** Route leads to different sales tiers based on budget. ```yaml theme={null} Conversation Node: Qualify_Budget message: "What's your budget range for this project?" extractVariables: - budget_amount: "Extract budget in dollars" transitions: - Always → Budget_Router Router Node: Budget_Router transitions: - Equation: {{budget_amount}} >= 50000 → Enterprise_Sales_Team - Structured Equation (logic: all): - {{budget_amount}} >= 10000 - {{budget_amount}} < 50000 → Mid_Market_Team - Structured Equation (logic: all): - {{budget_amount}} >= 1000 - {{budget_amount}} < 10000 → Small_Business_Team - Always → Self_Service_Flow ``` ### Example 3: Time-Based Routing **Scenario:** Different flows for business hours vs after hours. ```yaml theme={null} Router Node: Time_Router label: "Route based on business hours" transitions: - Structured Equation (logic: all): - {{current_hour}} >= 9 - {{current_hour}} < 17 - {{current_day_of_week}} != "Saturday" - {{current_day_of_week}} != "Sunday" → Business_Hours_Flow - Always → After_Hours_Flow ``` ### Example 4: Geographic Routing **Scenario:** Route to region-specific agents. ```yaml theme={null} Router Node: Region_Router transitions: - Structured Equation (logic: any): - {{caller_state}} == "CA" - {{caller_state}} == "OR" - {{caller_state}} == "WA" → West_Coast_Team - Structured Equation (logic: any): - {{caller_state}} == "NY" - {{caller_state}} == "NJ" - {{caller_state}} == "CT" → East_Coast_Team - Always → National_Team ``` ### Example 5: Customer Tier & Purchase History **Scenario:** VIP treatment for premium customers with purchase history. ```yaml theme={null} Tool Node: Lookup_Customer outputMapping: membership_tier: $.tier lifetime_value: $.lifetime_value last_purchase_days: $.days_since_purchase transitions: - Always → Customer_Router Router Node: Customer_Router transitions: # VIP path: Premium tier AND high lifetime value - Structured Equation (logic: all): - {{membership_tier}} == "premium" - {{lifetime_value}} >= 10000 → VIP_Concierge_Service # Loyal path: Recent purchase - Equation: {{last_purchase_days}} <= 30 → Active_Customer_Flow # Win-back path: No recent purchase - Structured Equation (logic: all): - {{last_purchase_days}} > 90 - {{membership_tier}} != "cancelled" → Reactivation_Campaign # Default path - Always → Standard_Service ``` ### Example 6: Multi-Factor Lead Scoring **Scenario:** Complex lead scoring with multiple factors. ```yaml theme={null} Conversation Node: Qualify_Lead extractVariables: - company_size: "Number of employees" - budget_range: "Annual budget" - timeline: "When to start" - decision_maker: "Are they the decision maker" transitions: - Always → Lead_Score_Router Router Node: Lead_Score_Router # High-priority leads transitions: - Structured Equation (logic: all): - {{company_size}} >= 100 - {{budget_range}} >= 50000 - {{timeline}} == "immediate" - {{decision_maker}} == true → Hot_Lead_Immediate_Transfer # Medium-priority leads - Structured Equation (logic: all): - {{company_size}} >= 20 - {{budget_range}} >= 10000 - {{decision_maker}} == true → Warm_Lead_Schedule_Demo # Low-priority leads - Structured Equation (logic: any): - {{company_size}} < 20 - {{budget_range}} < 10000 - {{decision_maker}} == false → Nurture_Campaign # Unqualified - Always → Self_Service_Resources ``` ### Example 7: Inventory-Based Routing **Scenario:** Different flows based on product availability. ```yaml theme={null} Tool Node: Check_Inventory outputMapping: stock_quantity: $.available next_shipment_days: $.next_shipment_in_days transitions: - Always → Inventory_Router Router Node: Inventory_Router transitions: # In stock - Equation: {{stock_quantity}} > 0 → Process_Order # Out of stock but coming soon - Structured Equation (logic: all): - {{stock_quantity}} == 0 - {{next_shipment_days}} <= 7 → Backorder_Option # Out of stock, long wait - Structured Equation (logic: all): - {{stock_quantity}} == 0 - {{next_shipment_days}} > 7 → Suggest_Alternatives # Unknown availability - Always → Manual_Check_Flow ``` ### Example 8: Payment Status Routing **Scenario:** Handle different payment outcomes. ```yaml theme={null} Tool Node: Process_Payment outputMapping: payment_status: $.status decline_reason: $.decline_reason transitions: - Always → Payment_Router Router Node: Payment_Router transitions: - Equation: {{payment_status}} == "succeeded" → Payment_Success_Flow - Equation: {{payment_status}} == "insufficient_funds" → Insufficient_Funds_Flow - Equation: {{payment_status}} == "card_declined" → Card_Declined_Flow - Equation: {{payment_status}} == "requires_authentication" → 3DS_Authentication_Flow - Always → Payment_Error_Flow ``` *** ## Advanced Patterns ### Nested Routers Chain multiple routers for complex decision trees. ```yaml theme={null} Router Node: Primary_Router transitions: - Equation: {{customer_type}} == "business" → Business_Size_Router - Equation: {{customer_type}} == "individual" → Individual_Income_Router - Always → Unknown_Router Router Node: Business_Size_Router transitions: - Equation: {{company_size}} >= 1000 → Enterprise_Flow - Equation: {{company_size}} >= 100 → Mid_Market_Flow - Always → Small_Business_Flow Router Node: Individual_Income_Router transitions: - Equation: {{annual_income}} >= 100000 → High_Net_Worth_Flow - Always → Standard_Individual_Flow ``` ### Router + Conversation Hybrid Use routers to branch, then personalize with conversation. ```yaml theme={null} Router Node: Tier_Router transitions: - Equation: {{tier}} == "premium" → Premium_Greeting - Always → Standard_Greeting Conversation Node: Premium_Greeting message: "Welcome back, {{name}}! As a premium member, you have priority access to our specialists." Conversation Node: Standard_Greeting message: "Thanks for calling! How can I help you today?" ``` ### A/B Testing Split traffic randomly or by criteria for testing. ```yaml theme={null} Router Node: AB_Test_Router label: "50/50 split for testing new flow" transitions: # Use session_id hash or random value to split - Equation: {{session_id}} contains "a" → Flow_Variant_A - Equation: {{session_id}} contains "b" → Flow_Variant_B - Always → Flow_Variant_A ``` ### Priority Escalation Route urgent cases immediately. ```yaml theme={null} Router Node: Priority_Router transitions: # Critical priority - Structured Equation (logic: any): - {{urgency}} == "critical" - {{account_value}} >= 100000 - {{is_escalation}} == true → Immediate_Human_Transfer # High priority - Structured Equation (logic: all): - {{urgency}} == "high" - {{issue_complexity}} == "complex" → Senior_Agent_Queue # Standard - Always → Standard_Support_Flow ``` *** ## Flow Examples ### Example Flow 1: Customer Service Routing ```mermaid theme={null} graph TD Start[Start: Lookup Customer] Router{Router
Account Status} Active[Active Account Flow] Trial[Trial Upsell] Suspended[Reactivation] New[New Customer] Start --> Router Router -->|"active"| Active Router -->|"trial"| Trial Router -->|"suspended"| Suspended Router -->|else| New ``` ### Example Flow 2: Lead Qualification ```mermaid theme={null} graph TD Qualify[Collect Lead Info] Router{Router
Lead Score} Hot[Hot Lead:
Immediate Transfer] Warm[Warm Lead:
Schedule Demo] Cold[Cold Lead:
Nurture Campaign] Qualify --> Router Router -->|"high score"| Hot Router -->|"medium score"| Warm Router -->|"low score"| Cold ``` ### Example Flow 3: Nested Decision Tree ```mermaid theme={null} graph TD Type{Customer Type} BizSize{Business Size} Income{Income Level} Enterprise[Enterprise Sales] MidMarket[Mid-Market] SmallBiz[Small Business] HighNet[High Net Worth] Standard[Standard Service] Type -->|"business"| BizSize Type -->|"individual"| Income BizSize -->|">1000"| Enterprise BizSize -->|">100"| MidMarket BizSize -->|else| SmallBiz Income -->|">100k"| HighNet Income -->|else| Standard ``` *** ## Troubleshooting ### Issue: Router always takes the same path **Possible causes:** * Variable not being set correctly * Variable value is different than expected * Always transition is first (catches everything) **Solution:** 1. Check variable extraction in previous nodes 2. Debug variable values using test calls 3. Verify transition order (always should be last) 4. Add logging to see actual variable values ### Issue: Flow gets stuck at router **Possible causes:** * No transition matches and no always fallback * Variable doesn't exist * Condition syntax error **Solution:** 1. Always add an "always" transition 2. Verify variables exist before router 3. Check condition syntax 4. Test with various input values ### Issue: Wrong path being taken **Possible causes:** * Variable type mismatch (string vs number) * Unexpected variable value * Condition logic error **Solution:** 1. Check variable data types 2. Use correct comparison operators 3. Test conditions independently 4. Review extracted variable values ### Issue: Cannot reference variable in router **Possible causes:** * Variable not extracted yet * Variable name typo * Wrong variable scope **Solution:** 1. Ensure variable is extracted before router 2. Check variable name spelling: `{{exact_name}}` 3. Verify variable is in scope 4. Review flow order *** ## Performance Considerations Router nodes are extremely fast: * **No LLM calls:** Pure logic evaluation * **No API requests:** Local computation * **Instant transitions:** Sub-millisecond routing * **Efficient:** Minimal resource usage **Best practices for performance:** * Use routers for high-volume routing * Prefer routers over conversation nodes for data-based decisions * Keep condition logic simple for fastest evaluation * Order transitions with most likely first *** ## Schema Reference ```typescript theme={null} { type: "router", label?: string, // Optional display label description?: string, // Optional internal description // Router nodes are pure logic - minimal config // All behavior is defined through transitions transitions: Array<{ id: string, name?: string, priority: number, // Higher = evaluated first isEnabled: boolean, condition: { type: "structured_equation" | "always", // For structured_equation logic?: "all" | "any", // AND or OR conditions?: Array<{ variable: string, operator: "equals" | "not_equals" | "greater_than" | "less_than" | "greater_than_or_equal" | "less_than_or_equal" | "contains" | "not_contains", value: string | number | boolean }>, // For always description?: string }, targetNodeId: string }>, position: { x: number, y: number } } ``` *** ## Next Steps Master all transition types and conditions Learn about variable extraction and usage Extract data to use in router conditions Collect data before routing Build better flows # Set Local Variables Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/set-local-variables-node Set variable values without conversation, then automatically advance to the next node ## Overview Set Local Variables nodes assign values to variables without any conversation. They execute instantly and automatically advance to the next connected node. Use them to initialize data, transform values, or prepare variables before they're needed downstream. **Key characteristic:** No conversation, no user interaction. The node sets variables and immediately moves on. ## When to Use Use Set Local Variables nodes to: * **Initialize variables** before a conversation or tool node needs them * **Transform data** — reformat, combine, or compute values from existing variables * **Set defaults** — provide fallback values for variables that may not be extracted yet * **Prepare API parameters** — assemble values before a tool node call * **Store computed results** — save derived data for later use in the flow *** ## Core Configuration ```typescript theme={null} { type: "set_local_variables", label?: string, description?: string, // Variables to set staticVariables?: Array<{ id: string, name: string, // snake_case, 1-50 chars description?: string, dataType: "string" | "number" | "boolean" | "array" | "object", value: string | number | boolean | any[] | object | null }>, // Transition (automatic — cannot be modified) transitions: Transition[] // Single auto-transition to next node } ``` Variables set in this node are available to all downstream nodes in the flow. *** ## Variable Configuration Each variable has four fields: | Field | Required | Description | | --------------- | -------- | --------------------------------------------------------------- | | **Name** | Yes | Variable name in `snake_case` format | | **Type** | Yes | Data type: String, Number, Boolean, Array (JSON), Object (JSON) | | **Value** | Yes | The value to assign — static or `{{variable}}` reference | | **Description** | No | Optional description for documentation | ### Value Input by Type | Type | Input | Example | | ----------- | ----------------------------------- | ---------------------------- | | **String** | Text input with variable support | `"hello"` or `{{user_name}}` | | **Number** | Numeric input with variable support | `42` or `{{order_total}}` | | **Boolean** | Toggle switch | `true` / `false` | | **Array** | JSON editor | `["item1", "item2"]` | | **Object** | JSON editor | `{"key": "value"}` | All value inputs support `{{variable}}` references, allowing you to set a variable based on another variable's value. *** ## Use Cases & Examples ### Example 1: Initialize Variables Before a Loop ```yaml theme={null} Set Local Variables: Init_Counter variables: - name: attempt_count type: number value: 0 - name: max_attempts type: number value: 3 → Attempt_Action ``` ### Example 2: Combine Variables ```yaml theme={null} Set Local Variables: Build_Full_Name variables: - name: full_name type: string value: "{{first_name}} {{last_name}}" → Greet_Customer ``` ### Example 3: Set Defaults ```yaml theme={null} Set Local Variables: Set_Defaults variables: - name: language type: string value: "en" - name: priority type: string value: "normal" → Collect_Info ``` ### Example 4: Prepare API Parameters ```yaml theme={null} Set Local Variables: Prepare_Booking variables: - name: booking_payload type: object value: {"customer_id": "{{customer_id}}", "date": "{{selected_date}}", "time": "{{selected_time}}"} → Submit_Booking_Tool ``` *** ## Transitions Set Local Variables nodes use an **automatic transition** — they execute and immediately advance to the next connected node. You cannot add, remove, or edit transitions on this node type. Connect the node's output to the next node in your flow. The connection is always unconditional. *** ## Flow Examples ### Pattern: Initialize → Collect → Process ```mermaid theme={null} graph LR Init[Set Variables:
Set Defaults] Collect[Conversation:
Gather Info] Process[Tool:
Submit Data] Init --> Collect --> Process ``` ### Pattern: Transform Between Nodes ```mermaid theme={null} graph LR Lookup[Tool:
Customer Lookup] Transform[Set Variables:
Format Data] Greet[Conversation:
Personalized Greeting] Lookup --> Transform --> Greet ``` *** ## Next Steps Override agent settings mid-flow Learn about the variable system Execute tools with variable parameters Route based on variable values # Start Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/start-node Flow entry point with dual modes: conversation or tool execution ## Overview The start node is the entry point for every flow agent. It's the first node executed when a call begins and must be present in every flow (you cannot delete it). Unlike other node types, the start node can operate in two distinct modes: **conversation mode** for greeting callers, or **tool mode** for pre-fetching data before any conversation begins. **Every flow has exactly one start node.** It cannot be deleted, but it can be configured in multiple ways to match your needs. ## Operating Modes ### Conversation Mode (Default) In conversation mode, the start node behaves like a standard conversation node—greeting the caller and initiating dialogue. **Best for:** * Standard flows that begin with a greeting * IVR-style menus with DTMF options * Flows where immediate conversation is needed * Initial qualification or triage ### Tool Mode In tool mode, the start node executes a tool before any conversation happens, allowing you to pre-fetch caller data or perform initial setup actions. **Best for:** * Looking up caller information from CRM * Checking account status before greeting * Pre-loading personalized data * Logging call initiation * Fetching context from external systems *** ## Configuration: Conversation Mode ### Basic Setup ```typescript theme={null} { type: "start", subType: "conversation", messageType: "prompt" | "static", message: string, // Optional: Variable extraction extractVariables: { enabled: boolean, variables: Variable[] } } ``` ### Message Types #### Prompt (Dynamic) The AI generates responses based on context and conversation flow. ```yaml theme={null} Start Node (Conversation - Prompt): subType: conversation messageType: prompt message: | ## Objective Welcome the caller warmly and identify their reason for calling. ## Instructions - Greet them professionally - Ask how you can help today - Listen for their main concern - Be friendly and patient ``` **AI might say:** * "Good morning! Thanks for calling Acme Corporation. How can I help you today?" * "Hi there! This is Acme Corp. What can I do for you?" #### Static (Fixed) The AI speaks exactly what you write, every time. ```yaml theme={null} Start Node (Conversation - Static): subType: conversation messageType: static message: 'Thank you for calling Acme Corporation. This call may be recorded for quality assurance. How may I help you today?' ``` **AI always says exactly this message.** ### DTMF Transitions Start nodes in conversation mode support DTMF transitions for IVR-style menus. **Example - Department Selection Menu:** ```yaml theme={null} Start Node (Conversation): messageType: static message: 'Welcome to Acme Corp. Press 1 for Sales, Press 2 for Support, Press 3 for Billing, or stay on the line to speak with an agent.' Transitions: - DTMF: key=1 → Sales_Department - DTMF: key=2 → Support_Department - DTMF: key=3 → Billing_Department - Always → General_Agent ``` DTMF transitions are evaluated immediately when the user presses a key, even while the agent is still speaking. This provides a responsive IVR experience. ### Variable Extraction Extract data from the initial conversation to use throughout the flow. ```yaml theme={null} Start Node (Conversation): messageType: prompt message: "Welcome! May I have your name and account number to get started?" Extract Variables: enabled: true variables: - name: customer_name description: "Customer's full name" extractionPrompt: "Extract the customer's full name" dataType: string isRequired: true - name: account_number description: "Account number" extractionPrompt: "Extract the account number (digits only)" dataType: string isRequired: true Transitions: - Natural Language: "Name and account number collected" → Verify_Account ``` **[→ Learn More: Variable Extraction](/agents/variables/introduction)** *** ## Configuration: Tool Mode ### Basic Setup ```typescript theme={null} { type: "start", subType: "tool", // Tool configuration is in agentSettings.tools where tool.nodeId === 'start' // No tool reference fields on the node itself // Error handling timeout: number, // milliseconds, default 30000 onErrorBehavior: "continue" | "retry" | "fail", errorMessage?: string, // Response customization overrideResponse: boolean, customResponse?: string, outputMapping: Record, // Processing message processingMessage?: string, processingMessageType: "static" | "prompt" // Default: "static" } ``` **Tool Reference:** When subType is 'tool', the tool configuration is stored in `agentSettings.tools` array where `tool.nodeId === 'start'`. The node itself doesn't contain tool details—only execution settings. ### Selecting a Tool When you switch to tool mode, you select from your tool library: 1. Click on the start node 2. Change **Sub Type** to "Tool" 3. Click **Select Tool** 4. Choose from your tool templates **What happens behind the scenes:** * Selecting a tool creates an entry in `agentSettings.tools` array * This entry has `nodeId: 'start'` to link it to the start node * Tool configuration (toolId, toolType, parameters, overrides) is stored in that entry * The start node itself only contains execution settings (timeout, error handling, output mapping) **Available tool types:** * **API Request (Function):** HTTP requests to external APIs * **MCP Server:** Model Context Protocol integrations * **Web Tool:** Browser-based tools for SDK deployments **\[→ Learn more about tools and configuration/features/tools)** ### Parameter Mapping Parameters and overrides are configured in the tool reference (stored in `agentSettings.tools`), not on the node itself. **Example - Caller Lookup:** ```yaml theme={null} # In agentSettings.tools array: Tool Reference: nodeId: 'start' # Links to start node toolId: 'crm-lookup-tool-id' toolType: 'FUNCTION' persistentId: 'crm_lookup' version: 1 overrides: parameters: phone_number: { { caller_id } } # System variable include_history: true # Static value fields: 'name,account,status' # Static value # On the start node: Start Node (Tool): subType: tool timeout: 10000 onErrorBehavior: continue outputMapping: customer_name: $.data.name customer_id: $.data.id account_status: $.data.account.status membership_tier: $.data.account.tier processingMessage: 'Please hold while I look up your information...' processingMessageType: static transitions: - Always → Personalized_Greeting ``` When you configure a tool in the UI, you don't need to manually edit the agentSettings.tools array. The interface handles the tool reference creation and linkage automatically. ### Output Mapping Extract data from tool responses into flow variables using JSON path syntax. **Response from CRM tool:** ```json theme={null} { "data": { "id": "CUST-12345", "name": "John Smith", "account": { "status": "active", "tier": "premium" } } } ``` **Output mapping:** ```yaml theme={null} Output Mapping: customer_name: $.data.name # "John Smith" customer_id: $.data.id # "CUST-12345" account_status: $.data.account.status # "active" membership_tier: $.data.account.tier # "premium" ``` **Use extracted variables in next node:** ```yaml theme={null} Conversation Node: Personalized_Greeting message: "Welcome back, {{customer_name}}! As a {{membership_tier}} member, I'm happy to help you today." ``` ### Error Handling Configure what happens when tool execution fails. **Continue (Recommended)** ```yaml theme={null} Error Handling: onErrorBehavior: continue errorMessage: "I'm having trouble accessing your account. Let's continue anyway." ``` Flow continues to next node even if tool fails. Use for non-critical operations. **Retry** ```yaml theme={null} Error Handling: onErrorBehavior: retry errorMessage: 'Let me try that again...' ``` Automatically retries the tool call. Use for intermittent failures. **Fail** ```yaml theme={null} Error Handling: onErrorBehavior: fail errorMessage: "I'm experiencing technical difficulties. Please try again later." ``` Stops flow execution. Use when tool is critical to conversation. ### Custom Response Override By default, the agent handles tool results silently. You can override this to speak custom messages. **Without override (silent):** ```yaml theme={null} Start Node (Tool): tool: Lookup_Caller overrideResponse: false # Agent says nothing, just transitions to next node ``` **With override (custom message):** ```yaml theme={null} Start Node (Tool): tool: Lookup_Caller overrideResponse: true customResponse: "Welcome back, {{customer_name}}! I see you're a {{membership_tier}} member with an {{account_status}} account." # Agent speaks this custom message using extracted variables ``` ### Processing Message Show a message while the tool executes (especially useful for slow APIs). **Static processing message:** ```yaml theme={null} Processing Message: message: 'One moment while I look up your information...' messageType: static ``` **Dynamic processing message:** ```yaml theme={null} Processing Message: message: 'Let me check your account details.' messageType: prompt ``` ### Timeout Configuration Set maximum wait time for tool execution. ```yaml theme={null} Tool Settings: timeout: 10000 # 10 seconds ``` Default: 30000ms (30 seconds). If a tool exceeds the timeout, it follows the `onErrorBehavior` setting. *** ## Use Cases ### Use Case 1: Standard Greeting (Conversation Mode) **Scenario:** Simple customer service greeting. ```yaml theme={null} Start Node (Conversation): subType: conversation messageType: static message: "Thank you for calling Acme Corporation. How can I help you today?" Transitions: - Natural Language: "User needs sales" → Sales_Flow - Natural Language: "User needs support" → Support_Flow - Always → General_Conversation ``` ### Use Case 2: IVR Menu (Conversation Mode + DTMF) **Scenario:** Department routing with keypad. ```yaml theme={null} Start Node (Conversation): subType: conversation messageType: static message: 'Welcome to Acme Corp. For Sales, press 1. For Support, press 2. For Billing, press 3. Or press 0 for the operator.' Transitions: - DTMF: key=1 → Sales_Department - DTMF: key=2 → Support_Department - DTMF: key=3 → Billing_Department - DTMF: key=0 → Operator_Transfer - Always → No_Input_Handler ``` ### Use Case 3: Personalized Greeting (Tool Mode) **Scenario:** Look up caller, greet by name. ```yaml theme={null} Start Node (Tool): subType: tool tool: Lookup_Customer_By_Phone Parameters: phone_number: { { caller_id } } Output Mapping: customer_name: $.name customer_tier: $.tier last_order_date: $.last_order Custom Response: overrideResponse: true customResponse: 'Welcome back, {{customer_name}}! How can I help you today?' Processing Message: message: 'Please hold while I pull up your account...' Transitions: - Always → Main_Conversation ``` ### Use Case 4: Account Status Check (Tool Mode) **Scenario:** Check if account is active before proceeding. ```yaml theme={null} Start Node (Tool): subType: tool tool: Check_Account_Status Parameters: phone: {{caller_id}} Output Mapping: account_status: $.status account_balance: $.balance account_id: $.id Error Handling: onErrorBehavior: continue errorMessage: "I couldn't find your account in our system. Let's verify your information." Transitions: - Equation: {{account_status}} == "active" → Active_Account_Flow - Equation: {{account_status}} == "suspended" → Suspended_Account_Flow - Always → New_Customer_Flow ``` ### Use Case 5: Call Logging (Tool Mode) **Scenario:** Log call start for analytics. ```yaml theme={null} Start Node (Tool): subType: tool tool: Log_Call_Initiation Parameters: caller_id: { { caller_id } } call_id: { { call_id } } timestamp: { { current_time } } agent_id: { { agent_id } } Error Handling: onErrorBehavior: continue # Silent failure - logging shouldn't block conversation Transitions: - Always → Welcome_Greeting ``` ### Use Case 6: Multi-Language Routing (Conversation + Tool) **Scenario:** Detect language, route to appropriate agent. ```yaml theme={null} Start Node (Conversation): subType: conversation messageType: static message: "Welcome to Acme Corporation. For English, press 1. Para español, oprima 2." Transitions: - DTMF: key=1 → English_Flow - DTMF: key=2 → Transfer_Spanish_Agent Transfer Agent Node: Transfer_Spanish_Agent agentId: "spanish-support-agent" transferMessage: "Let me connect you with our Spanish representative." ``` *** ## Flow Examples ### Example 1: Simple Customer Service ```mermaid theme={null} graph LR Start[Start Node
Conversation Mode
'How can I help?'] Sales[Sales Flow] Support[Support Flow] General[General Agent] Start -->|"needs sales"| Sales Start -->|"needs support"| Support Start -->|Always| General ``` ### Example 2: Personalized Experience ```mermaid theme={null} graph LR Start[Start Node
Tool Mode
Lookup Customer] Router{Router
Account Status?} Active[Active Flow] Suspended[Suspended Flow] New[New Customer] Start --> Router Router -->|"active"| Active Router -->|"suspended"| Suspended Router -->|else| New ``` ### Example 3: IVR with Operator Fallback ```mermaid theme={null} graph LR Start[Start Node
DTMF Menu
Press 1, 2, 3, or 0] Sales[Sales] Support[Support] Billing[Billing] Operator[Transfer to Operator] Default[No Input Handler] Start -->|"DTMF: 1"| Sales Start -->|"DTMF: 2"| Support Start -->|"DTMF: 3"| Billing Start -->|"DTMF: 0"| Operator Start -->|Always| Default ``` *** ## Troubleshooting ### Issue: Tool not appearing in selection **Possible causes:** * Tool is inactive * Tool not in current project * Browser cache issue **Solution:** 1. Verify tool is active in tool library 2. Refresh the page 3. Check tool project ownership ### Issue: Tool times out **Possible causes:** * API is slow * Timeout set too low * Network connectivity **Solution:** 1. Increase timeout value 2. Check API performance 3. Add retry logic 4. Use "continue" behavior to avoid blocking ### Issue: Variables not extracted from tool response **Possible causes:** * Incorrect JSON path in output mapping * API response format changed * Variable name mismatch **Solution:** 1. Check tool response format 2. Verify JSON path syntax (\$.data.field) 3. Test with API directly 4. Review output mapping configuration ### Issue: DTMF not working on start node **Possible causes:** * Transitions not configured correctly * DTMF key not selected * Using tool mode (DTMF only works in conversation mode) **Solution:** 1. Ensure start node is in conversation mode 2. Verify DTMF transitions are configured 3. Test with actual phone call ### Issue: Custom response not spoken **Possible causes:** * `overrideResponse` is false * `customResponse` is empty * Variables referenced don't exist **Solution:** 1. Set `overrideResponse: true` 2. Provide custom response text 3. Verify variable names match output mapping *** ## Schema Reference ### Conversation Mode Schema ```typescript theme={null} { type: "start", subType: "conversation", // Message configuration messageType: "static" | "prompt", message: string, // Required // Variable extraction extractVariables: { enabled: boolean, variables: Array<{ name: string, description?: string, dataType: "string" | "number" | "boolean", isRequired: boolean, extractionPrompt?: string }> } } ``` ### Tool Mode Schema ```typescript theme={null} { type: "start", subType: "tool", // Tool configuration is stored in agentSettings.tools where tool.nodeId === 'start' // Tool selection, parameters, and overrides are NOT on the node // Execution settings timeout: number, // milliseconds, default 30000 onErrorBehavior: "continue" | "retry" | "fail", // default: "continue" errorMessage?: string, // Response customization overrideResponse: boolean, // default: false customResponse?: string, outputMapping: Record, // JSON path mapping, default: {} // Processing message processingMessage?: string, processingMessageType: "static" | "prompt" // default: "static" } ``` **Where is the tool configuration?** The tool itself (including toolId, toolType, parameters, overrides, etc.) is configured in the `agentSettings.tools` array. The start node in tool mode only contains execution and response settings, not the tool reference itself. *** ## Next Steps Continue the conversation after start Execute additional tools in your flow Route based on extracted variables Learn about all transition types Master the variable system Understand DTMF capabilities # Tool Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/tool-node Execute reusable tool templates with parameter mapping and error handling ## Overview Tool nodes execute server-side tools from your tool library — API calls, database queries, and external integrations. They reference existing tool templates that can be reused across multiple agents and flows. **Key characteristic:** Tool nodes execute server-side actions and then transition to the next node based on results. For client-side browser actions, use the [Web Tool Node](./web-tool-node) instead. ## When to Use Use tool nodes to: * Look up customer data from CRM systems * Check inventory, availability, or status * Submit forms or create records * Process payments or transactions * Send notifications (email, SMS, webhooks) * Retrieve data from databases * Execute business logic on external systems * Call any HTTP API with reusable configuration **Use Tool Node when:** * The tool will be used in multiple places * The tool needs comprehensive documentation * The tool requires consistent configuration * You want centralized tool management **Use [Web Tool Node](./web-tool-node) instead when:** * You need client-side actions in the browser (UI navigation, modals, page interactions) * The tool should reuse existing frontend API integrations * The agent is deployed via the Voice Agents SDK on a website *** ## Core Configuration ### Basic Setup ```typescript theme={null} { type: "tool", label?: string, description?: string, // Tool configuration is stored in agentSettings.tools where tool.nodeId === node.id // No tool reference fields (toolId, toolName, toolType) on the node itself // Node-specific parameters (can override tool template parameters) parameters: ToolParameter[], // default: [] // Execution timeout: number, // milliseconds, default 30000 // Error handling onErrorBehavior: "continue" | "retry" | "fail", // default: "continue" errorMessage?: string, // Response handling overrideResponse: boolean, // default: false customResponse?: string, outputMapping: Record, // default: {} // Variable extraction extractVariables: ExtractVariablesConfig, // Put on hold putOnHold: boolean, // default: false — put user on hold while tool executes // Put on hold putOnHold: boolean, // default: false — put user on hold while tool executes // Processing message processingMessage?: string, processingMessageType: "static" | "prompt", // default: "static" // Transitions transitions: Transition[] } ``` **Tool Reference Architecture:** The tool itself (toolId, toolType, overrides, version) is stored in `agentSettings.tools` array with `tool.nodeId` matching this node's ID. The node only contains execution settings and parameter overrides. ### Selecting a Tool 1. Add a Tool Node to your flow 2. Click **Select Tool** in the node configuration 3. Choose from your tool library 4. Tool details auto-populate (name, description, parameters) **What happens behind the scenes:** * Selecting a tool creates an entry in `agentSettings.tools` array * This entry has `nodeId` set to this node's ID to link them * Tool configuration (toolId, toolType, persistentId, version, overrides) is stored in that entry * The node itself only contains execution settings (timeout, error handling, output mapping, parameters) **Available tool types:** * **FUNCTION:** Server-side HTTP API requests (full override support) * **MCP:** Model Context Protocol tools (no overrides allowed) **\[→ Learn more about tool types and architecture/features/tools)** *** ## Parameter Mapping Map flow variables and static values to tool input parameters. ### Static Values Hardcoded values that never change. ```yaml theme={null} Tool Node: Send_Welcome_Email tool: SendGrid_Email Parameters: template_id: "welcome-v2" from_email: "support@acme.com" from_name: "Acme Support Team" ``` ### Variable References Use data collected earlier in the flow using `{{variable_name}}` syntax. ```yaml theme={null} Tool Node: Send_Confirmation_Email tool: SendGrid_Email Parameters: to_email: {{customer_email}} to_name: {{customer_name}} template_id: "order-confirmation" order_id: {{order_id}} ``` ### System Variables Reference built-in system variables. ```yaml theme={null} Tool Node: Log_Call_Event tool: Analytics_Logger Parameters: caller_id: {{caller_id}} call_id: {{call_id}} timestamp: {{current_time}} agent_id: {{agent_id}} session_id: {{session_id}} ``` **[→ See all system variables: Variables Guide](/agents/variables/introduction)** ### Mixed Static and Variables Combine both for flexible configurations. ```yaml theme={null} Tool Node: CRM_Customer_Lookup tool: Salesforce_Query Parameters: phone: {{caller_phone}} # Variable include_orders: true # Static fields: "name,email,account_id" # Static limit: 1 # Static ``` ### Parameter Types Tool parameters can have different data types: ```typescript theme={null} { name: string, value: string, // Can contain {{variables}} type: "string" | "number" | "boolean" | "object", required: boolean } ``` **Example with mixed types:** ```yaml theme={null} Parameters: customer_name: { { name } } # string order_total: { { cart_total } } # number send_confirmation: true # boolean shipping_address: { { address_json } } # object ``` *** ## Output Mapping Extract data from tool responses into flow variables using JSON path syntax. ### JSON Path Syntax Use `$.path.to.field` notation to reference fields in the response. **Tool response:** ```json theme={null} { "success": true, "data": { "customer": { "id": "CUST-12345", "name": "John Smith", "email": "john@example.com" }, "account": { "status": "active", "balance": 1250.5, "tier": "premium" } } } ``` **Output mapping:** ```yaml theme={null} Output Mapping: customer_id: $.data.customer.id # "CUST-12345" customer_name: $.data.customer.name # "John Smith" customer_email: $.data.customer.email # "john@example.com" account_status: $.data.account.status # "active" account_balance: $.data.account.balance # 1250.50 membership_tier: $.data.account.tier # "premium" ``` ### Using Extracted Variables Variables extracted via output mapping become available immediately in subsequent nodes. ```yaml theme={null} Tool Node: Lookup_Account tool: CRM_Lookup outputMapping: customer_name: $.name account_balance: $.balance Conversation Node: Discuss_Account message: "Hello {{customer_name}}, I see your current balance is ${{account_balance}}." ``` ### Array Access Access array elements by index. **Response:** ```json theme={null} { "orders": [ { "id": "ORD-001", "total": 99.99 }, { "id": "ORD-002", "total": 149.99 } ] } ``` **Mapping:** ```yaml theme={null} Output Mapping: latest_order_id: $.orders[0].id # "ORD-001" latest_order_total: $.orders[0].total # 99.99 ``` ### Nested Objects Navigate deeply nested structures. ```yaml theme={null} Output Mapping: street: $.data.customer.address.street city: $.data.customer.address.city zip: $.data.customer.address.postal_code ``` *** ## Error Handling Configure how the flow responds when tool execution fails. ### Continue (Recommended for Non-Critical Tools) Flow continues even if tool fails. Best for optional operations. ```yaml theme={null} Tool Node: Update_CRM_Notes tool: CRM_Update_Notes Error Handling: onErrorBehavior: continue errorMessage: "I wasn't able to update your notes, but let's continue." Transitions: - Always → Next_Step ``` **Use when:** * Tool is non-critical (analytics, logging) * Flow can proceed without tool result * Degraded experience is acceptable ### Retry (For Intermittent Failures) Automatically retries failed tool calls. ```yaml theme={null} Tool Node: Check_Inventory tool: Inventory_API Error Handling: onErrorBehavior: retry errorMessage: "I'm having trouble checking inventory. Let me try again..." Transitions: - Equation: {{inventory_available}} > 0 → In_Stock_Flow - Always → Out_Of_Stock_Flow ``` **Use when:** * API has intermittent failures * Network issues are common * Tool is important but can fail temporarily ### Fail (For Critical Operations) Stops flow execution and ends call when tool fails. ```yaml theme={null} Tool Node: Process_Payment tool: Stripe_Charge Error Handling: onErrorBehavior: fail errorMessage: "I'm unable to process your payment at this time. Please try again later or contact support." Transitions: - Equation: {{payment_status}} == "success" → Payment_Success ``` **Use when:** * Tool is critical to conversation * Cannot proceed without successful result * Failure requires human intervention ### Error Messages Provide clear, user-friendly error messages. ```yaml theme={null} # ❌ Bad: Technical jargon errorMessage: "HTTP 500 Internal Server Error" # ✅ Good: User-friendly errorMessage: "I'm experiencing technical difficulties. Let me transfer you to a specialist who can help." ``` *** ## Response Handling ### Default Behavior (Silent) By default, tool nodes execute silently—no message is spoken about the tool execution. ```yaml theme={null} Tool Node: Lookup_Customer tool: CRM_Lookup overrideResponse: false # Default # Tool executes, extracts variables, transitions to next node # Agent says nothing about the tool call ``` ### Custom Response Override Speak a custom message after tool execution using extracted variables. ```yaml theme={null} Tool Node: Lookup_Customer tool: CRM_Lookup Output Mapping: customer_name: $.name account_tier: $.tier Response Override: overrideResponse: true customResponse: "Thank you, {{customer_name}}. I see you're a {{account_tier}} member." ``` **Variable interpolation:** * Use `{{variable_name}}` syntax * Variables from output mapping are available * Variables from earlier nodes are available * System variables are available ### Processing Message Show message while tool executes (especially for slow APIs). ```yaml theme={null} Tool Node: Search_Knowledge_Base tool: KB_Search Processing Message: message: "Let me search our knowledge base for that information..." messageType: static timeout: 15000 # 15 seconds ``` **Static vs Prompt:** **Static:** Exact message every time. ```yaml theme={null} processingMessage: 'Please hold while I check that for you...' processingMessageType: static ``` **Prompt:** AI generates contextual message. ```yaml theme={null} processingMessage: "Tell the user you're looking up their request and to please hold." processingMessageType: prompt ``` *** ## Variable Extraction In addition to output mapping (which extracts from tool responses), tool nodes support conversation-based variable extraction. ### When to Use Use variable extraction when: * Tool requires user confirmation before executing * You want to ask questions before calling the tool * Tool needs additional context from conversation ### Configuration ```yaml theme={null} Tool Node: Book_Appointment tool: Calendar_API Extract Variables: enabled: true variables: - name: preferred_date description: "Preferred appointment date" extractionPrompt: "Extract date in YYYY-MM-DD format" dataType: string isRequired: true - name: preferred_time description: "Preferred time" extractionPrompt: "Extract time in HH:MM format" dataType: string isRequired: true Parameters: customer_id: {{customer_id}} date: {{preferred_date}} time: {{preferred_time}} ``` **Note:** Variable extraction happens during conversation before tool execution. Most tool nodes use output mapping instead. *** ## Timeout Configuration Set maximum wait time for tool execution. ```yaml theme={null} Tool Node: External_API_Call tool: Slow_API timeout: 20000 # 20 seconds ``` **Recommendations:** * **Fast APIs (\< 2s):** 5000ms * **Standard APIs:** 10000ms * **Slow operations:** 20000-30000ms **When timeout occurs:** * Follows `onErrorBehavior` setting * Displays `errorMessage` if configured * Can continue, retry, or fail based on configuration Long timeouts create poor user experience. Consider async tools or processing messages for slow operations. *** ## Use Cases & Examples ### Example 1: Customer Lookup **Scenario:** Look up customer by phone number. ```yaml theme={null} Tool Node: Lookup_Customer tool: CRM_Customer_Lookup Parameters: phone_number: {{caller_id}} include_history: true Output Mapping: customer_id: $.data.id customer_name: $.data.name customer_email: $.data.email account_status: $.data.status membership_tier: $.data.tier last_order_date: $.data.last_order Response Override: overrideResponse: true customResponse: "Welcome back, {{customer_name}}! I have your account details." Error Handling: onErrorBehavior: continue errorMessage: "I'm having trouble accessing our customer database. Let's verify your information manually." Transitions: - Equation: {{account_status}} == "active" → Active_Account_Flow - Equation: {{account_status}} == "suspended" → Suspended_Flow - Always → New_Customer_Flow ``` ### Example 2: Check Inventory **Scenario:** Verify product availability before taking order. ```yaml theme={null} Conversation Node: Collect_Product_Info message: "What product are you interested in?" Extract Variables: - product_sku: "Extract product SKU or name" Transitions: - Always → Check_Stock Tool Node: Check_Stock tool: Inventory_Check_API Parameters: sku: {{product_sku}} warehouse: "primary" Output Mapping: stock_level: $.inventory.available next_restock_date: $.inventory.next_shipment Processing Message: message: "Let me check if we have that in stock..." messageType: static Error Handling: onErrorBehavior: retry Transitions: - Equation: {{stock_level}} > 0 → In_Stock_Flow - Equation: {{stock_level}} == 0 → Out_Of_Stock_Flow ``` ### Example 3: Process Payment **Scenario:** Charge customer credit card. ```yaml theme={null} Tool Node: Process_Payment tool: Stripe_Create_Charge Parameters: amount: {{order_total}} currency: "usd" customer_id: {{stripe_customer_id}} description: "Order #{{order_id}}" receipt_email: {{customer_email}} Output Mapping: charge_id: $.id payment_status: $.status receipt_url: $.receipt_url Processing Message: message: "Processing your payment. Please do not hang up..." messageType: static Error Handling: onErrorBehavior: fail errorMessage: "Your payment could not be processed. Please contact your bank or try a different payment method." Response Override: overrideResponse: true customResponse: "Your payment has been processed successfully. A receipt has been sent to {{customer_email}}." timeout: 15000 # 15 seconds Transitions: - Equation: {{payment_status}} == "succeeded" → Payment_Success - Always → Payment_Failed ``` ### Example 4: Send Notification **Scenario:** Send confirmation email after booking. ```yaml theme={null} Tool Node: Send_Confirmation_Email tool: SendGrid_Email Parameters: to: {{customer_email}} template_id: "appointment-confirmation" dynamic_data: { customer_name: {{customer_name}}, appointment_date: {{appointment_date}}, appointment_time: {{appointment_time}}, location: {{appointment_location}} } Processing Message: message: "I'm sending you a confirmation email now..." Error Handling: onErrorBehavior: continue errorMessage: "I wasn't able to send the confirmation email, but your appointment is booked." Transitions: - Always → Appointment_Confirmed ``` ### Example 5: Multi-Step Database Query **Scenario:** Look up customer, then fetch their orders. ```yaml theme={null} Tool Node: Lookup_Customer tool: Database_Query_Customer parameters: phone: {{caller_phone}} outputMapping: customer_id: $.id transitions: - Always → Fetch_Orders Tool Node: Fetch_Orders tool: Database_Query_Orders parameters: customer_id: {{customer_id}} limit: 5 outputMapping: order_count: $.total latest_order_id: $.orders[0].id latest_order_status: $.orders[0].status transitions: - Equation: {{order_count}} > 0 → Has_Orders_Flow - Always → No_Orders_Flow ``` ### Example 6: Conditional Tool Execution **Scenario:** Only call pricing API for premium members. ```yaml theme={null} Router Node: Check_Membership transitions: - Equation: {{membership_tier}} == "premium" → Get_Premium_Pricing - Always → Get_Standard_Pricing Tool Node: Get_Premium_Pricing tool: Pricing_API parameters: tier: "premium" customer_id: {{customer_id}} outputMapping: discount_percentage: $.discount transitions: - Always → Display_Pricing Tool Node: Get_Standard_Pricing tool: Pricing_API parameters: tier: "standard" outputMapping: discount_percentage: $.discount transitions: - Always → Display_Pricing ``` *** ## Transitions Tool nodes support all transition types: ### Natural Language Evaluate conversation context. ```yaml theme={null} Transitions: - Natural Language: "User is satisfied with the result" → Continue_Flow - Natural Language: "User wants to modify something" → Modify_Flow ``` **Note:** Tool nodes don't have conversations by default. Natural language transitions evaluate context from previous nodes. ### Structured Equation Route based on extracted variables. ```yaml theme={null} Transitions: - Equation: {{order_status}} == "completed" → Order_Complete - Equation: {{order_status}} == "pending" → Order_Pending - Equation: {{order_status}} == "failed" → Order_Failed ``` ### Always Fallback transition. ```yaml theme={null} Transitions: - Equation: {{success}} == true → Success_Path - Always → Error_Path ``` **[→ Learn More: Transitions](../transitions)** *** ## Troubleshooting ### Issue: Tool not appearing in selection **Solution:** 1. Verify tool exists in tool library 2. Check tool is active 3. Refresh the page 4. Verify tool is in current project ### Issue: Parameters not being sent correctly **Solution:** 1. Check variable names match exactly (case-sensitive) 2. Verify variables exist (were extracted earlier) 3. Review parameter type (string vs number vs boolean) 4. Test with static values first ### Issue: Output mapping not extracting variables **Solution:** 1. Verify JSON path syntax: `$.path.to.field` 2. Check actual API response format 3. Test JSON path with tool response 4. Ensure response contains expected fields ### Issue: Tool timeout **Solution:** 1. Increase timeout value 2. Check API performance 3. Add retry logic 4. Consider async tools 5. Add processing message ### Issue: Variables not available in next node **Solution:** 1. Verify output mapping is configured 2. Check variable names match exactly 3. Ensure tool completed successfully 4. Review flow transitions *** ## Schema Reference ```typescript theme={null} { type: "tool", label?: string, description?: string, // Tool configuration stored in agentSettings.tools (not on node) // Tool is linked via tool.nodeId === node.id // Node-specific parameters parameters: Array<{ name: string, value: string, // Supports {{variable}} syntax type: "string" | "number" | "boolean" | "object", required: boolean, // Enhanced fields for custom parameters description?: string, dataType?: "string" | "number" | "boolean" | "array" | "object", defaultValue?: string }>, // Execution settings timeout: number, // Default: 30000ms // Variable extraction (optional) extractVariables: { enabled: boolean, variables: Array }, // Response handling overrideResponse: boolean, // Default: false customResponse?: string, outputMapping: Record, // JSON path → variable name, default: {} // Error handling onErrorBehavior: "continue" | "retry" | "fail", // Default: "continue" errorMessage?: string, // Processing message processingMessage?: string, processingMessageType: "static" | "prompt", // Transitions transitions: Transition[], // Position position: { x: number, y: number } } ``` *** ## Next Steps Execute client-side browser tools Build reusable tool templates Route based on tool results Master variable usage and mapping Control flow after tool execution ``` ``` # Transfer Agent Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/transfer-agent-node Seamlessly transfer to another Hamsa AI agent while preserving conversation context ## Overview Transfer agent nodes hand off the conversation to a different Hamsa AI agent within your workspace. Unlike transfer call nodes that connect to external phone numbers, transfer agent nodes keep the conversation within your AI ecosystem with optional context preservation. **Key characteristic:** Transfer agent nodes maintain the call connection while switching which AI agent is handling the conversation—no phone system transfer needed. ## When to Use Use transfer agent nodes to: * **Specialist routing** - Technical support, billing, sales specialists * **Language switching** - English → Spanish → Mandarin agents * **Skill-based routing** - Route to agents with specific capabilities * **Complexity escalation** - Simple → advanced agent for complex issues * **Department handoff** - Different agents for different departments * **Workflow stages** - Lead qualification → sales closing agents * **Regional expertise** - Route to agents familiar with specific regions * **Product-specific agents** - Different agents for different product lines **Use Transfer Agent Node when:** * Destination is another Hamsa AI agent * Want the option to preserve conversation history and variables * Need faster, more reliable transfers than phone transfers * Staying within your AI agent ecosystem * Want seamless transitions without hold music or ringing **Use Transfer Call Node instead when:** * Transferring to human agents at phone numbers * Connecting to external phone systems * Regulatory requirements for human interaction * Need to connect to traditional phone lines **[→ Compare: Transfer Call Node](./transfer-call-node)** *** ## Core Configuration ```typescript theme={null} { type: "transfer_agent", label?: string, description?: string, // Target agent (required) agentId: string, // ID of the Hamsa agent to transfer to // Handoff options handoffConversation: boolean, // default: false — transfer conversation history handoffVariables: boolean, // default: false — transfer extracted variables // Transfer message (optional) transferMessage?: string, transferMessageType: "static" | "prompt", // Default: "static" // Timeout timeout: number, // milliseconds, default: 30000 // Global node settings isGlobal?: boolean, globalConditionType?: "prompt" | "dtmf", globalCondition?: string, globalDtmfKey?: string, // Transitions (usually none needed) transitions?: Transition[] } ``` *** ## Agent Selection ### Selecting the Target Agent 1. Click on the Transfer Agent Node 2. In configuration panel, click **Select Agent** 3. Choose from available agents in your workspace 4. Agent details auto-populate (name, ID) **Available agents:** * All Flow Agents in your workspace * All Single Prompt Agents in your workspace * Agents from same project You can only transfer to agents within your workspace. Agents in other workspaces are not accessible. ### Agent ID Each agent has a unique ID used for transfers. ```yaml theme={null} Transfer Agent Node: Transfer_To_Spanish agentId: "agent_abc123xyz" # Spanish support agent ``` ### Using Variables for Dynamic Routing ```yaml theme={null} # Extract or determine which agent to use Router Node: Language_Router transitions: - Equation: {{preferred_language}} == "spanish" → Transfer_Spanish - Equation: {{preferred_language}} == "french" → Transfer_French Transfer Agent Node: Transfer_Spanish agentId: "spanish_support_agent_id" Transfer Agent Node: Transfer_French agentId: "french_support_agent_id" ``` *** ## Transfer Message ### Static Message (Default) Exact message spoken before transfer. ```yaml theme={null} Transfer Agent Node: Transfer_To_Tech_Support agentId: "tech_support_agent" Transfer Message: message: "I'm connecting you with our technical specialist who can better assist you." messageType: static ``` **Use static when:** * Professional, consistent messaging * Short, simple transfer announcement * No personalization needed ### Prompt-Based Message AI generates contextual transfer message. ```yaml theme={null} Transfer Agent Node: Transfer_To_Billing agentId: "billing_agent" Transfer Message: message: "Explain to the user that you're transferring them to a billing specialist who can help with their specific question about invoices." messageType: prompt ``` **AI might say:** * "Let me connect you with our billing team who specializes in invoice questions." * "I'm getting you to someone in billing who can review your invoices." **Use prompt when:** * Want natural, conversational transfer * Personalization based on context * Flexible, adaptive messaging ### Message with Variables Reference conversation data in transfer message. ```yaml theme={null} Transfer Agent Node: Transfer_Premium_Support agentId: "premium_support_agent" Transfer Message: message: "Thank you {{customer_name}}. As a {{tier}} member, I'm connecting you with our premium support specialist." messageType: static ``` ### Silent Transfer (No Message) Omit transfer message for instant, seamless transition. ```yaml theme={null} Transfer Agent Node: Silent_Transfer agentId: "specialist_agent" # No transferMessage configured - instant transfer ``` *** ## Timeout Configuration Set maximum wait time for transfer to complete. ```yaml theme={null} Transfer Agent Node: Quick_Transfer agentId: "sales_agent" timeout: 15000 # 15 seconds ``` **Default:** 30000ms (30 seconds) **Range:** 1000ms - 60000ms (1-60 seconds) **Recommendations:** * **Agent transfers:** 15-30 seconds (faster than phone transfers) * **Critical transfers:** 10-15 seconds * **Non-critical:** 30 seconds Agent transfers are typically much faster than phone transfers since there's no phone system involved. Most complete in under 1 second. *** ## Handoff Options Transfer agent nodes can optionally pass context to the receiving agent. Both options are **off by default** — enable them when the new agent needs prior context. ### Handoff Conversation When enabled, the full conversation history (user inputs and agent responses) is transferred to the new agent. The receiving agent can reference what was discussed without asking the user to repeat themselves. ```yaml theme={null} Transfer Agent Node: Transfer_To_Billing agentId: "billing_agent" handoffConversation: true # New agent sees full chat history ``` ### Handoff Variables When enabled, all extracted variables from the current flow are passed to the new agent and available in its prompts. ```yaml theme={null} Transfer Agent Node: Transfer_To_Specialist agentId: "specialist_agent" handoffVariables: true # New agent has access to {{customer_name}}, {{account_id}}, etc. ``` ### Both Enabled (Full Context Transfer) For a seamless handoff where the new agent has complete context: ```yaml theme={null} Transfer Agent Node: Transfer_Premium_Support agentId: "premium_support_agent" handoffConversation: true handoffVariables: true transferMessage: "I'm connecting you with a specialist who has your full details." ``` The receiving agent can immediately reference previous conversation and extracted data — no repeated questions. Both `handoffConversation` and `handoffVariables` default to **false**. If you need the new agent to have context, you must explicitly enable them. *** ## Use Cases & Examples ### Example 1: Language Switching **Scenario:** Transfer English speaker to Spanish-speaking agent. ```yaml theme={null} Conversation Node: Detect_Language message: "For English, press 1. Para español, oprima 2." transitions: - DTMF: key=1 → English_Flow - DTMF: key=2 → Transfer_Spanish Transfer Agent Node: Transfer_Spanish agentId: "spanish_support_agent_id" Transfer Message: message: "Let me connect you with our Spanish-speaking representative." messageType: static timeout: 15000 ``` ### Example 2: Technical Support Escalation **Scenario:** Basic support agent transfers complex technical issues. ```yaml theme={null} Conversation Node: Diagnose_Issue message: "Can you describe the technical problem you're experiencing?" Extract Variables: - issue_description: "Description of the issue" - issue_complexity: "Rate complexity: simple, moderate, complex" transitions: - Equation: {{issue_complexity}} == "complex" → Transfer_Tech_Specialist - Always → Attempt_Basic_Support Transfer Agent Node: Transfer_Tech_Specialist agentId: "advanced_tech_support_agent" Transfer Message: message: "This sounds like a complex issue. Let me connect you with one of our senior technical specialists who can help." messageType: static ``` ### Example 3: Department Routing **Scenario:** Route to specialized department agents. ```yaml theme={null} Conversation Node: Identify_Department message: "Are you calling about sales, technical support, or billing?" transitions: - Natural Language: "sales" → Transfer_Sales - Natural Language: "technical" → Transfer_Tech - Natural Language: "billing" → Transfer_Billing Transfer Agent Node: Transfer_Sales agentId: "sales_specialist_agent" transferMessage: "Connecting you with our sales team." Transfer Agent Node: Transfer_Tech agentId: "tech_support_agent" transferMessage: "Connecting you with technical support." Transfer Agent Node: Transfer_Billing agentId: "billing_specialist_agent" transferMessage: "Connecting you with our billing department." ``` ### Example 4: VIP Customer Routing **Scenario:** High-value customers get specialized agent. ```yaml theme={null} Tool Node: Lookup_Customer outputMapping: customer_tier: $.tier lifetime_value: $.ltv transitions: - Always → Tier_Router Router Node: Tier_Router transitions: - Structured Equation (logic: all): - {{customer_tier}} == "vip" - {{lifetime_value}} >= 50000 → Transfer_VIP_Concierge - Always → Standard_Support Transfer Agent Node: Transfer_VIP_Concierge agentId: "vip_concierge_agent" Transfer Message: message: "As a VIP member, I'm connecting you with your dedicated concierge specialist." messageType: static ``` ### Example 5: Product Specialist Routing **Scenario:** Route to agents specialized in specific products. ```yaml theme={null} Conversation Node: Identify_Product message: "Which product do you need help with?" Extract Variables: - product_name: "Product name" transitions: - Always → Product_Router Router Node: Product_Router transitions: - Equation: {{product_name}} contains "Enterprise" → Transfer_Enterprise_Specialist - Equation: {{product_name}} contains "API" → Transfer_API_Specialist - Always → Transfer_General_Product_Support Transfer Agent Node: Transfer_Enterprise_Specialist agentId: "enterprise_product_agent" transferMessage: "Connecting you with our Enterprise product specialist." Transfer Agent Node: Transfer_API_Specialist agentId: "api_specialist_agent" transferMessage: "Let me connect you with our API specialist." ``` ### Example 6: Sales Pipeline Handoff **Scenario:** Qualification agent hands off to closing agent. ```yaml theme={null} Conversation Node: Qualify_Lead message: "Let me understand your needs..." Extract Variables: - budget: "Budget amount" - timeline: "Purchase timeline" - decision_maker: "Are they the decision maker" transitions: - Always → Qualification_Router Router Node: Qualification_Router transitions: - Structured Equation (logic: all): - {{budget}} >= 10000 - {{timeline}} == "immediate" - {{decision_maker}} == true → Transfer_Closing_Agent - Always → Continue_Nurture Transfer Agent Node: Transfer_Closing_Agent agentId: "sales_closing_specialist" Transfer Message: message: "Based on your needs, I'm connecting you with {{sales_rep_name}} who can finalize the details with you." messageType: static ``` ### Example 7: After-Hours Language Support **Scenario:** Route to 24/7 multilingual support after hours. ```yaml theme={null} Router Node: Hours_And_Language_Check transitions: - Structured Equation (logic: all): - {{current_hour}} < 9 OR {{current_hour}} >= 17 - {{preferred_language}} != "english" → Transfer_24_7_Multilingual - Always → Standard_Support Transfer Agent Node: Transfer_24_7_Multilingual agentId: "multilingual_24_7_agent" Transfer Message: message: "I'm connecting you with our 24/7 multilingual support team." messageType: static ``` ### Example 8: Global Transfer (Anytime Access) **Scenario:** Press 9 anytime to speak with a supervisor agent. ```yaml theme={null} Transfer Agent Node: Supervisor_Transfer # Global configuration isGlobal: true globalConditionType: dtmf globalDtmfKey: 9 # Transfer configuration agentId: "supervisor_agent_id" Transfer Message: message: "I'm transferring you to a supervisor now." messageType: static ``` *** ## Advantages Over Phone Transfers | Feature | Transfer Agent Node | Transfer Call Node | | ------------------------ | -------------------------- | ------------------------ | | **Speed** | Faster (no phone transfer) | Slower (phone system) | | **Context** | Optional (handoff toggles) | Lost (new call) | | **Reliability** | Very high | Depends on phone network | | **User Experience** | Seamless | Hold music, ringing | | **Costs** | No additional cost | Telephony transfer costs | | **Variables** | Optional (handoff toggle) | Not transferred | | **Conversation History** | Optional (handoff toggle) | Starts fresh | | **Setup** | Just agent ID | Phone number needed | *** ## Global Agent Transfers Make transfer agent nodes accessible from anywhere in the flow. ### Global via DTMF ```yaml theme={null} Transfer Agent Node: Global_Supervisor isGlobal: true globalConditionType: dtmf globalDtmfKey: 9 agentId: "supervisor_agent_id" transferMessage: "Connecting you with a supervisor." ``` Press 9 from any node to transfer to supervisor. ### Global via Natural Language ```yaml theme={null} Transfer Agent Node: Global_Specialist_Request isGlobal: true globalConditionType: prompt globalCondition: "User asks for a specialist or expert" agentId: "specialist_agent_id" transferMessage: "I'm connecting you with a specialist." ``` Say "I need a specialist" from any node to trigger transfer. **[→ Learn More: Global Nodes](../global-nodes)** *** ## Troubleshooting ### Issue: Transfer fails **Possible causes:** * Target agent doesn't exist * Target agent is inactive * Invalid agent ID * Agent in different workspace **Solution:** 1. Verify agent exists and is active 2. Check agent ID is correct 3. Ensure agent is in same workspace 4. Test with different agent ### Issue: Context not available in new agent **Possible causes:** * Variables not extracted before transfer * Variable scope issue * Agent configuration error **Solution:** 1. Verify variables are extracted before transfer 2. Check variable names are correct 3. Ensure variables are properly scoped 4. Test variable availability ### Issue: Transfer message not playing **Possible causes:** * Message field is empty * Message type misconfigured * Silent transfer configured **Solution:** 1. Add transfer message content 2. Verify messageType setting 3. Check if silent transfer is intended ### Issue: Timeout occurring **Possible causes:** * Target agent has issues * Network problems * Timeout set too short **Solution:** 1. Check target agent configuration 2. Increase timeout value 3. Test agent directly 4. Review agent logs *** ## Flow Examples ### Example Flow 1: Department Routing ```mermaid theme={null} graph LR Start[Start: Greeting] Identify{Conversation:
Which dept?} Sales[Transfer: Sales Agent] Tech[Transfer: Tech Agent] Billing[Transfer: Billing Agent] Start --> Identify Identify -->|"sales"| Sales Identify -->|"tech"| Tech Identify -->|"billing"| Billing ``` ### Example Flow 2: Complexity-Based Routing ```mermaid theme={null} graph TD Support[Basic Support Agent] Resolve{Router:
Can Resolve?} End[End Call] Specialist[Transfer: Specialist Agent] Support --> Resolve Resolve -->|"yes"| End Resolve -->|"complex"| Specialist ``` ### Example Flow 3: VIP Routing ```mermaid theme={null} graph TD Lookup[Tool: Lookup Customer] Router{Router:
Customer Tier?} VIP[Transfer: VIP Agent] Standard[Standard Support] Lookup --> Router Router -->|"vip"| VIP Router -->|"standard"| Standard ``` *** ## Schema Reference ```typescript theme={null} { type: "transfer_agent", label?: string, description?: string, // Target agent (required) agentId: string, // UUID or ID of target Hamsa agent // Handoff options handoffConversation: boolean, // default: false handoffVariables: boolean, // default: false // Transfer message (optional) transferMessage?: string, transferMessageType: "static" | "prompt", // Default: "static" // Timeout timeout: number, // milliseconds, default: 30000 // Global node settings isGlobal?: boolean, globalConditionType?: "prompt" | "dtmf", globalCondition?: string, // For prompt-based global globalDtmfKey?: "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "*" | "#", // Transitions (optional, rarely needed) transitions?: Transition[], // Position position: { x: number, y: number } } ``` *** ## Next Steps Transfer to external phone numbers Route to appropriate agent Make transfers accessible anytime Pass context to new agent Create and manage agents Build better flows # Transfer Call Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/transfer-call-node Transfer phone calls to another number with warm or cold handoff options ## Overview Transfer call nodes transfer the active phone call to another phone number. This is useful for escalating to human agents, routing to specialized departments, or connecting callers to specific phone lines. Transfer call nodes support both warm transfers (with announcement) and cold transfers (immediate connection). **Key characteristic:** Transfer call nodes connect the caller to a completely different phone number, ending the AI agent's involvement in the conversation. ## When to Use Use transfer call nodes to: * **Escalate to human agents** - Complex issues requiring human judgment * **Department routing** - Transfer to sales, support, billing departments * **Specialist connection** - Route to subject matter experts * **After-hours routing** - Transfer to answering service outside business hours * **Emergency scenarios** - Critical situations requiring immediate human attention * **Geographic routing** - Connect to local office phone numbers * **Compliance requirements** - Legal or regulatory requirements for human interaction **Use Transfer Call Node when:** * Caller needs to speak with a person at a phone number * Issue is beyond AI agent's capabilities * Regulatory or compliance requirements demand human interaction * Specialized expertise is required **Use Transfer Agent Node instead when:** * Transferring to another Hamsa AI agent * Want to maintain conversation context and history * Need faster, more reliable handoff * Staying within your AI agent ecosystem **[→ Compare: Transfer Agent Node](./transfer-agent-node)** *** ## Core Configuration ```typescript theme={null} { type: "transfer_call", label?: string, description?: string, // Phone number (required) phoneNumber: string, // E.164 format: +1234567890 // Transfer type transferType: "warm" | "cold", // Default: "cold" // Transfer message (optional) transferMessage?: string, transferMessageType: "static" | "prompt", // Default: "prompt" // Timeout timeout: number, // milliseconds, default: 30000 // Global node settings isGlobal?: boolean, globalConditionType?: "prompt" | "dtmf", globalCondition?: string, globalDtmfKey?: string, // Transitions (optional - usually none needed) transitions?: Transition[] } ``` *** ## Phone Number Format Phone numbers must be in **E.164 international format**. ### E.164 Format ``` +[country code][area code][local number] ``` **Valid examples:** ``` +14155551234 (USA) +442071234567 (UK) +61212345678 (Australia) +33123456789 (France) ``` **Invalid examples:** ``` ❌ (415) 555-1234 (Not E.164) ❌ 415-555-1234 (Missing country code) ❌ 14155551234 (Missing + prefix) ❌ +1-415-555-1234 (Contains dashes) ``` ### Country Codes Common country codes: * **USA/Canada:** +1 * **UK:** +44 * **Australia:** +61 * **Germany:** +49 * **France:** +33 ### Using Variables ```yaml theme={null} Transfer Call Node: Dynamic_Transfer phoneNumber: {{support_phone_number}} # Variable must contain E.164 formatted number ``` Invalid phone number format will cause transfer to fail. Always validate E.164 format. *** ## Transfer Types ### Cold Transfer (Default) Immediately transfer the call without announcement. The caller is connected directly to the destination number. ```yaml theme={null} Transfer Call Node: Operator_Transfer phoneNumber: +18005551234 transferType: cold # No transfer message - immediate connection ``` **User experience:** 1. Agent: "Let me transfer you now." 2. *Call immediately transfers* 3. Caller hears ringing or destination's greeting 4. AI agent disconnects **Use cold transfer when:** * Speed is important * No context needs to be provided * Destination will identify itself (IVR, receptionist) * Simple, straightforward routing ### Warm Transfer Announce the transfer before connecting. The agent speaks a transfer message, then connects the call. ```yaml theme={null} Transfer Call Node: Sales_Transfer phoneNumber: +18005551234 transferType: warm Transfer Message: message: "I'm transferring you to our sales team who can better assist you with pricing and packages." messageType: static ``` **User experience:** 1. Agent: "I'm transferring you to our sales team..." 2. *Agent speaks full message* 3. *Call transfers after message completes* 4. Caller hears ringing or destination's greeting **Use warm transfer when:** * Caller should know why they're being transferred * Setting expectations about who they'll reach * Professional, courteous experience * Context or explanation needed *** ## Transfer Message Configuration ### Static Message Exact, predetermined message spoken every time. ```yaml theme={null} Transfer Message: message: 'Let me connect you with a specialist who can help. Please hold.' messageType: static ``` **Use static when:** * Message should be identical every time * Legal or compliance requirements * Scripted professional transfer * No personalization needed ### Prompt-Based Message AI generates contextual transfer message based on conversation. ```yaml theme={null} Transfer Message: message: "Explain to the user that you're transferring them to a billing specialist who can help with their account balance question." messageType: prompt ``` **AI might say:** * "I'm connecting you with our billing team who specializes in account balances." * "Let me get you to someone in billing who can review your account." **Use prompt when:** * Want natural, conversational transfer * Personalization based on conversation context * Flexible, adaptive messaging * Reference extracted variables ### Message with Variables Use extracted variables in transfer messages. ```yaml theme={null} Transfer Message: message: "Thank you {{customer_name}}. I'm transferring you to {{department_name}} now." messageType: static ``` *** ## Timeout Configuration Set maximum wait time for transfer connection. ```yaml theme={null} Transfer Call Node: Support_Transfer phoneNumber: +18005551234 timeout: 45000 # 45 seconds ``` **Default:** 30000ms (30 seconds) **Range:** 1000ms - 60000ms (1-60 seconds) **What happens on timeout:** * Transfer attempt is cancelled * Call returns to flow (if transitions configured) * Otherwise, call typically ends **Recommendations:** * **Standard transfers:** 30 seconds * **Busy departments:** 45-60 seconds * **Quick routing:** 15-20 seconds If the destination doesn't answer within the timeout, the transfer fails. Plan for timeout scenarios with fallback transitions. *** ## Custom SIP Headers Attach custom SIP headers to the outgoing transfer call. This is useful for passing metadata to the receiving SIP endpoint — routing hints, customer context, or authentication tokens. Each header is a key-value pair where the value supports `{{variable}}` interpolation, making headers dynamic per-call. ```yaml theme={null} Transfer Call Node: Transfer_With_Context phoneNumber: +18005551234 transferType: warm sipHeaders: - name: X-Customer-Id value: "{{customer_id}}" - name: X-Call-Reason value: "{{call_reason}}" - name: X-Priority value: "high" ``` ### Adding Headers 1. Click **Add Header** in the Custom SIP Headers section 2. Enter the **Header Name** (e.g., `X-Custom-Header`) 3. Enter the **Value** — either a static string or a `{{variable}}` reference 4. Both name and value are required *** ## Use Cases & Examples ### Example 1: Simple Operator Transfer **Scenario:** Transfer to operator with no announcement. ```yaml theme={null} Transfer Call Node: Operator phoneNumber: +18005550100 transferType: cold ``` ### Example 2: Department Routing with Message **Scenario:** Route to sales with warm transfer. ```yaml theme={null} Conversation Node: Qualify_Need message: "Are you calling about sales, support, or billing?" transitions: - Natural Language: "sales" → Transfer_Sales - Natural Language: "support" → Transfer_Support - Natural Language: "billing" → Transfer_Billing Transfer Call Node: Transfer_Sales phoneNumber: +18005551001 transferType: warm Transfer Message: message: "I'm connecting you with our sales team who can discuss pricing and packages." messageType: static timeout: 30000 ``` ### Example 3: Emergency Transfer (Global) **Scenario:** Global node for urgent issues, accessible anytime via DTMF 0. ```yaml theme={null} Transfer Call Node: Emergency_Transfer # Global configuration isGlobal: true globalConditionType: dtmf globalDtmfKey: 0 # Transfer configuration phoneNumber: +18005550911 transferType: cold Transfer Message: message: "Transferring you to emergency support now." messageType: static ``` ### Example 4: After-Hours Routing **Scenario:** Transfer to answering service outside business hours. ```yaml theme={null} Router Node: Business_Hours_Check transitions: - Structured Equation (logic: all): - {{current_hour}} >= 9 - {{current_hour}} < 17 - {{current_day_of_week}} != "Saturday" - {{current_day_of_week}} != "Sunday" → Business_Hours_Flow - Always → After_Hours_Transfer Transfer Call Node: After_Hours_Transfer phoneNumber: +18005559999 transferType: warm Transfer Message: message: "Our offices are currently closed. I'm transferring you to our after-hours answering service who can take a message or help with urgent matters." messageType: static timeout: 45000 ``` ### Example 5: Escalation with Context **Scenario:** Transfer with personalized context about the caller. ```yaml theme={null} Tool Node: Lookup_Customer outputMapping: customer_name: $.name account_id: $.id issue_type: $.current_issue transitions: - Always → Escalate_Transfer Transfer Call Node: Escalate_Transfer phoneNumber: +18005552222 transferType: warm Transfer Message: message: "Thank you for your patience, {{customer_name}}. I'm transferring you to a specialist who can help with your {{issue_type}} issue. Your account number is {{account_id}}." messageType: static ``` ### Example 6: VIP Customer Routing **Scenario:** High-value customers get direct line to VIP team. ```yaml theme={null} Router Node: Customer_Tier_Check transitions: - Equation: {{customer_tier}} == "vip" → VIP_Transfer - Always → Standard_Support Transfer Call Node: VIP_Transfer phoneNumber: +18005550VIP transferType: warm Transfer Message: message: "As a VIP member, I'm connecting you directly with our premium support team." messageType: static timeout: 20000 # VIP gets faster answer ``` ### Example 7: Geographic Routing **Scenario:** Transfer to regional office based on location. ```yaml theme={null} Router Node: Region_Router transitions: - Equation: {{caller_state}} == "CA" → West_Coast_Office - Equation: {{caller_state}} == "NY" → East_Coast_Office - Always → National_Line Transfer Call Node: West_Coast_Office phoneNumber: +14155551234 transferType: warm transferMessage: "Connecting you to our San Francisco office." Transfer Call Node: East_Coast_Office phoneNumber: +12125551234 transferType: warm transferMessage: "Connecting you to our New York office." ``` ### Example 8: Timeout Fallback **Scenario:** Handle transfer timeout with fallback to voicemail. ```yaml theme={null} Transfer Call Node: Attempt_Transfer phoneNumber: +18005551234 timeout: 30000 transferType: warm transferMessage: "Let me connect you with our team." # Transitions handle timeout transitions: - Natural Language: "transfer failed or timeout" → Leave_Voicemail Conversation Node: Leave_Voicemail message: "Our team is currently unavailable. Would you like to leave a message or try again later?" ``` *** ## Global Transfer Nodes Make transfer nodes accessible from anywhere in the flow. ### Global via DTMF Press a key anytime to transfer (common: 0 for operator). ```yaml theme={null} Transfer Call Node: Global_Operator isGlobal: true globalConditionType: dtmf globalDtmfKey: 0 phoneNumber: +18005550100 transferType: cold ``` **User can press 0 at any point to immediately transfer.** ### Global via Natural Language Speak trigger phrase anytime to transfer. ```yaml theme={null} Transfer Call Node: Global_Human_Agent isGlobal: true globalConditionType: prompt globalCondition: "User wants to speak to a human agent or operator" phoneNumber: +18005550100 transferType: warm transferMessage: "I'm connecting you with a live agent now." ``` **User can say "I want to speak to a person" at any point.** ### Common Global Transfer Patterns ```yaml theme={null} # Operator (DTMF 0) Transfer Call Node: isGlobal: true globalConditionType: dtmf globalDtmfKey: 0 phoneNumber: +18005550100 # Emergency (DTMF *) Transfer Call Node: isGlobal: true globalConditionType: dtmf globalDtmfKey: * phoneNumber: +18005550911 # Speak to human (Natural language) Transfer Call Node: isGlobal: true globalConditionType: prompt globalCondition: "User requests human agent, operator, or live person" phoneNumber: +18005550100 ``` **[→ Learn More: Global Nodes](../global-nodes)** *** ## Transitions Most transfer call nodes don't need transitions—they terminate the AI agent's involvement. ### When to Use Transitions **Timeout handling:** ```yaml theme={null} Transfer Call Node: Busy_Support phoneNumber: +18005551234 timeout: 30000 transitions: - Always → Leave_Voicemail_Option ``` **Conditional flow continuation:** ```yaml theme={null} # Rare use case: Continue flow after failed transfer Transfer Call Node: Optional_Transfer transitions: - Natural Language: "transfer failed" → Continue_AI_Support - Always → End_Call ``` **In practice:** Most transfer call nodes have no transitions and simply end the call after transfer. *** ## Troubleshooting ### Issue: Transfer fails immediately **Possible causes:** * Invalid phone number format * Phone number doesn't exist * Network connectivity issues * Invalid country code **Solution:** 1. Verify E.164 format: `+[country][area][number]` 2. Test phone number manually 3. Check country code is correct 4. Remove any spaces, dashes, or parentheses ### Issue: Transfer times out **Possible causes:** * Destination number not answering * Timeout set too short * Destination line is busy * After-hours (no one available) **Solution:** 1. Increase timeout value 2. Verify destination is staffed 3. Test during business hours 4. Add fallback transition for timeout ### Issue: Transfer message not playing **Possible causes:** * Using cold transfer (no message in cold transfer) * Message is empty * Message type misconfigured **Solution:** 1. Use `transferType: warm` for messages 2. Verify message field has content 3. Check messageType is set correctly ### Issue: User disconnects during transfer **Possible causes:** * Long wait time (timeout) * No context provided (user confused) * Unexpected transfer (user didn't request it) **Solution:** 1. Use warm transfer with explanation 2. Set appropriate expectations 3. Reduce wait time 4. Only transfer when appropriate ### Issue: Variables not interpolating in message **Possible causes:** * Variable doesn't exist * Variable name misspelled * Variable not extracted yet **Solution:** 1. Verify variable exists (extracted earlier) 2. Check spelling: `{{exact_variable_name}}` 3. Ensure extraction happens before transfer 4. Test with static message first *** ## Flow Examples ### Example Flow 1: Simple Department Routing ```mermaid theme={null} graph LR Start[Start: Greeting] Menu{Conversation
Which department?} Sales[Transfer: Sales] Support[Transfer: Support] Start --> Menu Menu -->|"sales"| Sales Menu -->|"support"| Support ``` ### Example Flow 2: Smart Routing with Qualification ```mermaid theme={null} graph TD Start[Start: Greeting] Qualify[Conversation: Qualify Issue] Router{Router:
Can AI Handle?} AI[AI Support Flow] Human[Transfer: Human Agent] Start --> Qualify Qualify --> Router Router -->|"simple issue"| AI Router -->|"complex"| Human ``` ### Example Flow 3: Escalation Path ```mermaid theme={null} graph TD Support[AI Support] Resolved{Router:
Issue Resolved?} End[End Call] Escalate[Transfer: Specialist] Support --> Resolved Resolved -->|"yes"| End Resolved -->|"no"| Escalate ``` *** ## Comparison: Transfer Call vs Transfer Agent | Feature | Transfer Call Node | Transfer Agent Node | | ------------------- | ------------------------ | ------------------------------ | | **Destination** | Phone number | Hamsa AI agent | | **Speed** | Slower (phone system) | Faster (no phone transfer) | | **Reliability** | Depends on phone network | More reliable | | **Context** | Lost (new call) | Preserved (full history) | | **User Experience** | Hold music, ringing | Seamless transition | | **Use Case** | Human agents, external | Other AI agents | | **Costs** | Telephony transfer costs | No transfer costs | | **Best For** | Escalation to humans | Routing between AI specialists | **[→ Learn More: Transfer Agent Node](./transfer-agent-node)** *** ## Schema Reference ```typescript theme={null} { type: "transfer_call", label?: string, description?: string, // Phone number (required) phoneNumber: string, // E.164 format: +1234567890 // Transfer type transferType: "warm" | "cold", // Default: "cold" // Transfer message (for warm transfers) transferMessage?: string, transferMessageType: "static" | "prompt", // Default: "prompt" // Timeout timeout: number, // milliseconds, default: 30000 (30 seconds) // Custom SIP Headers (optional) sipHeaders?: Array<{ id: string, name: string, // e.g. "X-Custom-Header" value: string // Static value or {{variable}} reference }>, // Global node settings isGlobal?: boolean, globalConditionType?: "prompt" | "dtmf", globalCondition?: string, // For prompt-based global globalDtmfKey?: "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "*" | "#", // Transitions (optional) transitions?: Transition[], // Position position: { x: number, y: number } } ``` *** ## Next Steps Transfer to another Hamsa AI agent Make transfers accessible anytime Route before transferring End calls gracefully Use keypad for transfer triggers Build better flows # Web Tool Node Source: https://docs.tryhamsa.com/agents/flow-agent/nodes/web-tool-node Execute client-side browser tools within your flow with output mapping and conditional routing ## Overview The Web Tool Node executes a [Web Tool](/agents/tools/web-tools) — a client-side JavaScript function that runs in the user's browser via the Hamsa Voice Agents SDK. Unlike the [Tool Node](./tool-node) which calls server-side APIs, web tool nodes trigger actions directly in your web application. For example, when a user says "show me my cart", the agent can call a web tool that opens the cart drawer on your website — no server round-trip needed. Web tools also let you reuse your existing client-side API integrations rather than rebuilding them as server-side tools, saving development time when the web is your primary channel. Web tools only work on **web calls** (via the Voice Agents SDK). They do not function on phone calls — there is no browser to execute them. ## Use Cases * **Navigate the UI** — "Show me my dashboard" → routes the user to a specific page * **Open UI elements** — "I need to upload a document" → opens the upload modal * **Read page state** — Agent reads current form values or page context to give relevant answers * **Leverage existing auth** — The browser already has the user's session, so web tools can call authenticated APIs without re-passing credentials to the server * **Trigger client-side flows** — "Schedule a demo" → opens the booking widget * **Interact with embedded content** — Play a video, center a map on a location, expand a section ## Adding a Web Tool Node 1. Open your Flow Agent 2. Click **Add Node** and select **Web Tool Node** 3. Select a registered web tool from the tool selector (only `WEB_TOOL` type tools are shown) 4. Configure output mapping and transitions ## Configuration ### Processing Message Configure a message the agent speaks while the web tool executes: * **Static**: A fixed message (e.g., `"One moment while I look that up..."`) * **Prompt**: An AI-generated message that can reference variables (e.g., `"Let me find the {{product_category}} for you..."`) ### Tool Configuration Overrides Once a web tool is attached, you can override its default configuration for this specific node instance: * **Name** — Override the tool name * **Description** — Override the tool description * **Parameters** — Customize the parameter definitions * **Custom Parameters** — Add additional parameters * **Async** — Toggle async execution These overrides only apply to this node — the original web tool definition remains unchanged. ### Example Response Since web tools run client-side and cannot be tested from the server, the Web Tool Node provides an **Example Response** field. Paste a sample JSON or plain string response that your web tool would return. This allows you to: * Validate variable extraction paths before deployment * Test output mapping without executing the tool * Preview how transitions will evaluate against the response ### Custom Response When enabled, define a custom template for what the agent says after the tool runs, using extracted values from the response. ### Output Mapping and Variables Extract specific values from the web tool's JSON response and store them as variables: ```yaml theme={null} Web Tool Node: Check_Cart Output Mapping: cart_total: $.total item_count: $.items.length ↓ (Equation: {{cart_total}} > 100) Conversation Node: "Your cart total is {{cart_total}}. Would you like to checkout?" ↓ (Equation: {{cart_total}} <= 100) Conversation Node: "You have {{item_count}} items. Can I help you find anything else?" ``` In a single prompt agent, the web tool's response goes directly to the LLM without extraction. In a flow agent, you control exactly which values are extracted and how they're used. ## Transitions Web Tool Nodes support the following transition types: * **Prompt**: Route based on natural language evaluation of the response * **Equation**: Route based on extracted values from the response ## Web Tool Node vs Tool Node | Aspect | Web Tool Node | Tool Node | | ---------------- | ------------------------------------ | ----------------------------------------- | | Execution | Client-side in the browser | Server-side API call | | Works on | Web calls only | All call types | | Tool type | `WEB_TOOL` | `FUNCTION` / `MCP` | | Server testing | Not supported — use Example Response | Supported | | Override options | Name, description, params, async | Full: URL, method, headers, auth, timeout | ## Related Full web tools documentation with SDK registration and examples Server-side tool execution for API calls Use extracted tool data in your flow Route based on tool responses # Flow Agent Overview Source: https://docs.tryhamsa.com/agents/flow-agent/overview Build sophisticated conversation flows with visual node-based editor ## What is a Flow Agent? Flow agents allow you to create sophisticated conversation flows using a visual node-based editor. Instead of relying on a single prompt, you build structured workflows where each node represents a specific step or action in your conversation, with transitions that define how the conversation progresses. ## When to Use Flow Agents Flow agents are ideal when: * Your conversation has multiple distinct stages or branches * You need conditional logic based on user responses or data * You want visual representation of conversation paths * You need fine-grained control over different conversation stages * You're building complex workflows with tool integrations * You want to reuse conversation components * Your single prompt would exceed 500 words ## Core Concepts ### Nodes Nodes are the fundamental building blocks of your conversation flow. Each node represents a specific step or action in your agent's conversation, with its own logic, behavior, and purpose. ### Edges Edges connect nodes and represent the flow of conversation from one node to another. They're created by adding transitions to nodes. ### Transitions Transitions define the conditions under which the conversation moves from one node to another. Multiple transitions can exist on a single node, creating branching logic. ### Variables Variables store and pass data between nodes (and are also used in single-prompt agents). They include: * **System Variables**: Built-in variables like `call_id`, `user_number`, `current_time` * **Extracted Variables**: Data collected from conversations and tools (flow agent only) * **Custom Variables**: Workflow-level variables you define (available in flow and single-prompt agents) **[→ Variable System](/agents/variables/introduction)** — Full docs live in the Variables section (flow + single-prompt). ## Benefits of Flow Agents ### 🎯 Precise Control Define exact behavior for each conversation scenario, with different prompts, voice settings, and tools per node. ### 📊 Visual Clarity See your entire conversation flow at a glance, making it easy to understand and communicate with stakeholders. ### 🔧 Better Performance Fine-tune specific parts of the conversation without affecting others. Use different LLM models per node to optimize cost and quality. ### 🐛 Easier Debugging Isolate and fix issues quickly with real-time node highlighting and detailed logs showing exactly where the conversation is. ### ♻️ Reusability Create modular conversation components that can be reused across different agents or workflows. ### 🔀 Complex Logic Handle sophisticated decision trees, parallel processes, and dynamic routing based on real-time data. ## Node Types Hamsa provides 10 different node types to build comprehensive conversation flows: ### 1. **Start Node** Every flow begins with a start node. Can operate in two modes: * **Conversation Mode**: Greets the user and starts dialogue * **Tool Mode**: Executes a tool before any conversation begins **[→ Learn More: Start Node](./nodes/start-node)** ### 2. **Conversation Node** The most commonly used node type for having conversations with users. Each conversation node has its own focused prompt and behavior. **Key Features:** * Dynamic or static messages * Variable extraction * DTMF input capture * Skip response mode * Block interruptions **[→ Learn More: Conversation Node](./nodes/conversation-node)** ### 3. **Tool Node** Execute custom functions or API calls. Choose from: * **Function Tools**: Custom API integrations * **Web Tools**: Simple HTTP requests * **MCP Tools**: Model Context Protocol tools **[→ Learn More: Tool Node](./nodes/tool-node)** ### 4. **Web Tool Node** Client-side browser tools that run in the user's browser via the Hamsa Voice Agents SDK. Only available for web calls. **[→ Learn More: Web Tool Node](./nodes/web-tool-node)** ### 5. **Router Node** Create conditional branches based on logic without having a conversation. Pure routing based on variables and equations. **[→ Learn More: Router Node](./nodes/router-node)** ### 6. **Transfer Call Node** Transfer the call to another phone number. Supports: * Warm transfers (with context) * Cold transfers (direct) **[→ Learn More: Transfer Call Node](./nodes/transfer-call-node)** ### 7. **Transfer Agent Node** Switch to a different Hamsa agent during the conversation, maintaining call context and history. **Advantages:** * Lower latency than phone transfers * Better reliability (no new call needed) * Full conversation history passed * No repeated questions **[→ Learn More: Transfer Agent Node](./nodes/transfer-agent-node)** ### 8. **End Call Node** Terminate the conversation. Can include a final message before ending. **[→ Learn More: End Call Node](./nodes/end-call-node)** ### 9. **Set Local Variables Node** Set variable values without any conversation. Assign static or computed values, then automatically advance to the next node. **[→ Learn More: Set Local Variables Node](./nodes/set-local-variables-node)** ### 10. **Change Agent Settings Node** Override agent settings (voice, call behavior, system prompt) mid-flow without conversation. Changes apply from that point forward. **[→ Learn More: Change Agent Settings Node](./nodes/change-agent-settings-node)** ## Transition Types Control how conversations progress between nodes using five types of transitions: ### 1. **Natural Language (Prompt)** The LLM evaluates whether a condition described in natural language is met. **Example:** "User wants to speak to a human agent" ### 2. **Structured Equation** Hardcoded mathematical/logical conditions using variables. **Example:** `{{user_age}} > 18 AND {{location}} == "USA"` ### 3. **DTMF (Keypad)** Trigger transitions based on phone keypad presses (0-9, \*, #). **Example:** Press 1 for Sales, Press 2 for Support ### 4. **Always** Fallback transition that always triggers if no other conditions are met. ### 5. **Auto** Automatic transition used by nodes that don't require user interaction (Set Local Variables, Change Agent Settings). The node executes and immediately advances to the connected node. **[→ Learn More: Transition Conditions](./transitions)** ## Global Nodes Some nodes need to be accessible from anywhere in the conversation flow because they handle universal scenarios: * Emergency support routing * "Speak to operator" (triggered by pressing 0) * "Repeat menu" (triggered by pressing 9) * Common objection handling **How to create:** Mark any node as "Global" and define its trigger (prompt or DTMF key). **[→ Learn More: Global Nodes](./global-nodes)** ## Variable System Hamsa's powerful variable system enables dynamic, context-aware conversations: ### System Variables Always available throughout the flow — time variables (`current_time`, `current_date`, etc.), call variables (`call_id`, `direction`, `call_start_time`), user variables (`user_number`, `user_number_area_code`), and agent variables (`agent_name`, `agent_id`, `agent_number`). See the full reference in the Variables section. ### Extracted Variables Collect data from conversations using variable extraction in conversation nodes. ### Custom Variables Define workflow-level variables for data you'll provide via API. **[→ Learn More: Variable System](/agents/variables/introduction)** ## DTMF Features Hamsa provides three distinct DTMF (phone keypad) features: ### 1. **Simple DTMF Transitions** Create IVR-style menus: "Press 1 for Sales, Press 2 for Support" ### 2. **DTMF Input Capture** Collect sequences of digits (account numbers, PINs, phone numbers) and store in variables. ### 3. **Global DTMF Triggers** Allow keypad presses to trigger global nodes from anywhere: "Press 0 for operator at any time" **[→ Learn More: DTMF Features](./dtmf)** ## Setup Process Creating a flow agent follows these main steps: ### Step 1: Configure Global Settings * Select default voice and language * Choose LLM model and temperature * Configure default call behavior settings * Set up knowledge bases and global tools * Define custom variables **[→ Learn More: Global Settings](./global-settings)** ### Step 2: Design Your Flow * Add a start node * Create conversation nodes for different stages * Add tool nodes for integrations * Connect nodes with transitions * Add router nodes for complex branching ### Step 3: Add Transition Conditions * Define when to move between nodes * Use natural language or structured equations * Set up DTMF keypad triggers * Configure fallback (always) paths ### Step 4: Configure Individual Nodes * Write focused prompts for each conversation node * Set up variable extraction * Configure DTMF input capture * Enable/disable interruptions per node * Override voice or LLM settings when needed ### Step 5: Test & Debug * Use visual debugging with node highlighting * Review real-time logs during test calls * Verify all transition paths work correctly * Test edge cases and error scenarios **[→ Learn More: Testing & Debugging](./debugging)** ## Example Use Cases ### Multi-Department Call Routing **Nodes:** Start → Main Menu (with DTMF) → Sales Branch → Support Branch → Billing Branch → Transfer/End **Flow:** User presses keypad to select department, then conversations tailored to each department's needs. ### Appointment Booking with Availability Check **Nodes:** Start → Collect Info → Check Availability (Tool) → Router (available?) → Book Appointment (Tool) OR Suggest Alternatives → Confirmation → End **Flow:** Collects customer info, checks real-time availability, books if available, or offers alternatives. ### Customer Support with Escalation **Nodes:** Start → Initial Triage → Knowledge Base Search (Tool) → Router (resolved?) → End OR Transfer to Agent **Global Node:** "Speak to human" accessible anytime via natural language or DTMF 0 **Flow:** Attempts to resolve with AI, escalates when needed or requested. ### Lead Qualification Pipeline **Nodes:** Start → Collect Company Info → Budget Router → High Value Path (immediate transfer) → Medium Value Path (schedule callback) → Low Value Path (nurture sequence) → End **Flow:** Qualifies leads, routes high-value leads to sales immediately, others to appropriate nurture paths. ## Advanced Features ### Model Overrides per Node Use GPT-4.1 for complex reasoning nodes, GPT-4.1-Mini for simple confirmations—optimize cost and performance. ### Voice Settings per Node Different voices for different conversation stages or personalities. ### Processing Messages Display messages while tools execute: "Let me check that for you..." ### Variable Extraction with Context Rules Intelligent recommendations for variables based on conversation context. ### Validation System Real-time validation catches errors before deployment: * Missing required fields * Unreachable nodes * Invalid variable references * Circular dependencies ## Feature Comparison: Flow Agent vs Single Prompt | Feature | Single Prompt | Flow Agent | | --------------------- | -------------------- | ----------------------------- | | **Setup Complexity** | Low | Medium | | **Visual Design** | ❌ No | ✅ Yes | | **Conditional Logic** | Limited (in prompt) | ✅ Unlimited | | **Multiple Prompts** | ❌ Single | ✅ Per node | | **Tool Integration** | ✅ Up to \~3 | ✅ Unlimited | | **DTMF Support** | ❌ No | ✅ Full (3 features) | | **Variable System** | System + custom vars | ✅ System + custom + extracted | | **Reusability** | Low | ✅ High | | **Debugging** | Basic logs | ✅ Visual + detailed logs | | **Model per Stage** | ❌ One model | ✅ Override per node | | **Agent Transfer** | ❌ No | ✅ Yes | | **Best For** | Simple flows | Complex workflows | ## Next Steps Ready to build your first flow agent? 1. **[Configure Global Settings](./global-settings)** - Set up defaults for your workflow 2. **[Understand Node Types](./nodes/overview)** - Learn about all available node types 3. **[Master Transitions](./transitions)** - Control conversation flow 4. **[Variable System](/agents/variables/introduction)** - Pass data between nodes 5. **[DTMF Features](./dtmf)** - Add keypad interactions 6. **[Test & Debug](./debugging)** - Ensure quality before deployment 7. **[Best Practices](./best-practices)** - Tips for building reliable flows *** **Start simple?** Consider **[Single Prompt Agents](../single-prompt/overview)** for straightforward use cases. # Transitions Source: https://docs.tryhamsa.com/agents/flow-agent/transitions Control conversation flow with natural language, equations, DTMF, and auto transitions Transitions define when and how the conversation moves from one node to another. Each node can have multiple transitions; the first matching transition fires. ## Transition Types | Type | Evaluation | Use Case | | ------------ | ------------ | -------------------------------------------------------- | | **Prompt** | LLM-based | Natural language condition — intent detection, sentiment | | **Equation** | Rule-based | Variable comparisons, thresholds | | **DTMF** | Keypad input | IVR menus, quick selection | | **Auto** | Automatic | Auto-advance when node completes | *** ## Availability by Node Type Not all transition types are available on every node. Some nodes have fixed transitions that cannot be added, removed, or edited. | Node Type | Available Transitions | | ----------------------------------- | --------------------------------------------------------- | | **Conversation** | Prompt, DTMF, Auto | | **Start** (conversation mode) | Prompt, DTMF | | **Start** (tool mode) | Fixed: "On Success" and "On Failure" (cannot be modified) | | **Router** | Equation only, plus a fixed "Else" fallback | | **Tool / Web Tool** | Fixed: "On Success" and "On Failure" (cannot be modified) | | **Transfer Call / Transfer Agent** | Fixed: "On Failure" only (cannot be modified) | | **Set Variables / Change Settings** | Fixed: auto-transition (cannot be modified) | | **End Call** | None (terminal node) | **Fixed transitions** on Tool, Web Tool, Transfer, and Start (tool mode) nodes are pre-configured and cannot be added, removed, or edited by the user. *** ## Prompt Transitions (Natural Language) The LLM evaluates whether the condition is met based on the caller's input and conversation context. ### Configuration ```typescript theme={null} { type: 'natural_language', prompt: string, // Condition description (required) description?: string } ``` ### Examples ```yaml theme={null} Prompt: "The user wants to speak with a human agent" → Target: Transfer_to_Agent Prompt: "The user is asking about billing or payment issues" → Target: Billing_Department Prompt: "The user agrees or says yes" → Target: Confirm_Path Prompt: "The user declines or says no" → Target: Alternative_Path ``` Write conditions that describe user intent, not exact phrases. "The user wants to speak with a human" matches "get me an agent", "transfer me", "I need a person", etc. *** ## Equation Transitions (Structured) Equation transitions evaluate variable conditions using rule-based logic — no LLM involved. They are only available on **Router** nodes. ### Configuration ```typescript theme={null} { type: 'structured_equation', logic: 'all' | 'any', // AND or OR conditions: Array<{ variable: string, operator: Operator, value: string | number | boolean, description?: string }>, description?: string } ``` ### Operators | Operator | Symbol | Description | | ----------------------- | ------ | ----------------------------- | | `equals` | `=` | Exact match | | `not_equals` | `≠` | Not equal | | `greater_than` | `>` | Numeric greater than | | `less_than` | `<` | Numeric less than | | `greater_than_or_equal` | `≥` | Numeric greater than or equal | | `less_than_or_equal` | `≤` | Numeric less than or equal | | `contains` | `∋` | String contains substring | | `not_contains` | `∌` | String does not contain | | `exists` | `∃` | Variable has any value | | `not_exists` | `∄` | Variable is null/undefined | | `regex` | `(.*)` | Regular expression match | When using numeric operators (`>`, `≥`, `<`, `≤`), the variable must be a number or convertible to a number. Hamsa handles type coercion automatically — a string `"25"` compared to number `21` with `greater_than` evaluates correctly. ### Examples **Single condition:** ```yaml theme={null} Variable: account_status Operator: equals Value: 'active' → Target: Active_Account_Path ``` **AND logic (all conditions must pass):** ```yaml theme={null} Logic: all Conditions: - account_balance > 1000 - account_type equals "premium" → Target: VIP_Path ``` **OR logic (any condition passes):** ```yaml theme={null} Logic: any Conditions: - support_tier equals "platinum" - is_enterprise equals true → Target: Priority_Support ``` **Existence check:** ```yaml theme={null} Variable: customer_id Operator: exists → Target: Known_Customer_Path ``` ### Router "Else" Fallback Every router node has a fixed "Else" transition that acts as the default fallback when no equation conditions match. This transition cannot be removed or edited — it is always present and always evaluated last. ```yaml theme={null} Router Node: "Account Router" Transitions: - Equation: account_type equals "premium" → Premium_Flow - Equation: account_type equals "standard" → Standard_Flow - Else → Basic_Flow # Fixed, cannot be removed ``` *** ## DTMF Transitions DTMF transitions fire when the caller presses a specific keypad key. They are available on **Conversation** and **Start** nodes. → See [DTMF Features](./dtmf) for full documentation on all DTMF capabilities. ### Configuration ```typescript theme={null} { type: 'dtmf', key: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '*' | '#', description?: string } ``` ### Example ```yaml theme={null} Conversation Node: "Main Menu" Message: "Press 1 for Sales, Press 2 for Support, Press 3 for Billing" Transitions: - DTMF: key=1 → Sales_Department - DTMF: key=2 → Support_Department - DTMF: key=3 → Billing_Department ``` ### DTMF Capture Restrictions When [DTMF input capture](./dtmf) is enabled on a node, DTMF transitions are restricted: * Only the termination keys (`*` and `#`) can be used as transition keys — number keys (0–9) are disabled. * A maximum of 2 DTMF transitions are allowed (one for each termination key). * Any existing number-key transitions are automatically disabled. * Keys already used for [global node](./global-nodes) triggers are also unavailable. *** ## Auto Transitions Auto transitions advance to the next node automatically when the current node completes. They are only available on **Conversation** nodes. ### Configuration ```typescript theme={null} { type: 'auto', description: string // Defaults to "Auto-advance" } ``` ### Example ```yaml theme={null} Conversation Node: "Greeting" Message: "Welcome! Let me transfer you to the right department." Transitions: - Auto → Route_Department ``` ### Behavior Adding an auto transition has significant effects on the node: * **All existing transitions are disabled** — they are kept but marked inactive. * **All existing connection edges are deleted** — only the auto-transition connection remains. * **You cannot have both auto and manual transitions** on the same node. When you later remove the auto transition to switch back to manual transitions, previously disabled transitions are re-enabled, but you will need to manually reconnect the edges. *** ## Return to Source When a node has **Return to Source** enabled, all transitions on that node are disabled. The node returns control to whichever node called it instead of following any transition path. Toggle off "Return to Source" to re-enable transitions. *** ## Advanced Patterns ### Combining prompt and DTMF ```yaml theme={null} Conversation Node: "Support Menu" Message: "Describe your issue, or press 0 for an agent" Transitions: - DTMF: key=0 → Transfer_Agent - Prompt: "urgent issue" → Urgent - Prompt: "billing" → Billing ``` ### Time-based routing ```yaml theme={null} Router Node: "Hours Check" Transitions: - Equation: Logic=all Conditions: - current_hour >= 9 - current_hour < 17 Target: Business_Hours_Flow - Else → After_Hours_Flow ``` *** ## Validation The flow builder validates transitions before deployment: * All transitions have non-empty conditions (prompts, equation conditions, DTMF keys) * DTMF keys are valid (0–9, \*, #) * DTMF termination keys do not conflict between input capture and transitions * Numeric operators must have numeric values or variable references *** ## Transition Schema ```typescript theme={null} interface Transition { id: string; name?: string; condition: | NaturalLanguageCondition | StructuredEquationCondition | DTMFCondition | AutoCondition | AlwaysCondition; targetNodeId: string; isEnabled: boolean; } ``` *** ## Next Steps Nodes reachable from anywhere in the flow Full keypad interaction documentation Variables used in equation conditions Pure routing without conversation # Voice Agents Source: https://docs.tryhamsa.com/agents/introduction Build intelligent AI voice agents for phone and web Hamsa is a comprehensive platform for building, testing, deploying, and monitoring reliable AI voice agents. Our platform provides complete solutions for creating conversational AI agents that interact naturally over the phone or on the web, with advanced features for both simple and complex conversation flows. ## What are Voice Agents? Voice agents are AI-powered conversational systems that interact with users in natural language through voice. They can be deployed over phone calls (via telephony) or embedded directly into your website or app using the [Hamsa Voice Agents SDK](/developers/sdks/voice-agents-web-sdk). They can: * Answer questions and provide information * Collect data from callers * Make decisions based on conversation context * Execute actions like transferring calls or sending SMS * Access your company's knowledge base * Integrate with your existing systems via tools and APIs ## Key Capabilities ### Natural Conversations Our agents support natural, human-like conversations in multiple languages and dialects, with advanced speech recognition and synthesis capabilities. ### Intelligent Decision Making Powered by leading LLM models (GPT-4.1, Gemini, etc.), agents can understand context, handle complex scenarios, and make intelligent decisions during conversations. ### Flexible Architecture Choose between simple single-prompt agents for straightforward use cases, or powerful flow-based agents for complex, multi-step conversations. ### Enterprise-Ready Features * Real-time call monitoring and testing * Comprehensive logging and analytics * Knowledge base integration * Custom tool/function calling * Webhook integrations * Phone number management and web SDK deployment ## Two Approaches to Building Agents Hamsa offers two distinct approaches for building voice agents, each suited to different complexity levels and use cases: ### 1. Single Prompt Agent A single prompt agent uses one comprehensive prompt to define all agent behaviors, making it the simplest approach to get started. Perfect for simple information gathering, basic customer support, and quick prototypes. **Explore Single Prompt Agent:** Understand the basics of single prompt agents Learn how to write effective prompts for your agent Configure how your agent handles calls Customize the voice and speech characteristics Add advanced AI features to your agent Fine-tune your agent's technical configuration ### 2. Flow Agent Flow agents allow you to create complex, visual conversation flows with multiple nodes and conditional transitions. Ideal for multi-step processes, advanced call routing, and integration-heavy applications. **Explore Flow Agent:** Introduction to visual conversation flows Configure settings that apply across your entire flow Manage nodes that are accessible from anywhere in the flow Use and manage conversation data with variables Define the logic for moving between nodes Handle keypad input during calls Tools and techniques for troubleshooting flows Tips for building reliable and effective flow agents #### Nodes Reference ## Getting Started 1. **Choose Your Agent Type** - Decide between Single Prompt or Flow Agent based on your use case 2. **Configure Global Settings** - Set up voice, language, LLM model, and behavior settings 3. **Design Your Conversation** - Write prompts (Single Prompt) or design flow (Flow Agent) 4. **Add Integrations** - Connect knowledge bases, tools, and webhooks 5. **Test Thoroughly** - Use our browser and phone testing capabilities 6. **Deploy** - Assign a phone number for telephony, or integrate the [Voice Agents SDK](/developers/sdks/voice-agents-web-sdk) for web ## Platform Features Hamsa provides comprehensive features across the entire agent lifecycle: * **Build**: Intuitive UI for creating and configuring agents * **Test**: Real-time testing in browser or via phone call * **Monitor**: Live call monitoring with detailed logs * **Deploy**: Phone numbers for telephony, or the [Voice Agents SDK](/developers/sdks/voice-agents-web-sdk) for web * **Integrate**: Knowledge bases, custom tools, webhooks, and more * **Optimize**: LLM configuration, voice customization, and performance tuning Ready to build your first voice agent? Let's get started! # Best Practices Source: https://docs.tryhamsa.com/agents/knowledge-base/best-practices Guidance for structuring and maintaining your knowledge base Engineer-validated best practices for the knowledge base will be added here over time. ## Content Tips * Use clear, specific language — agents retrieve and cite content verbatim, so precision matters * Give items descriptive names so you can find and manage them later * Keep each item focused on one topic; splitting large documents by chapter or section generally works better than a single large upload * Include dates in names for versioned content (e.g. "Return Policy - 2024") ## Related Documentation Learn how to create knowledge base items Organize and maintain your knowledge base Monitor item processing and health # Overview Source: https://docs.tryhamsa.com/agents/knowledge-base/creating-items Step-by-step guide to creating text, file, and URL items ## Overview Knowledge base items can be created in three ways: * **Text Items**: Direct text input * **File Items**: Upload documents * **URL Items**: Import web content All items are processed automatically after creation. Processing time varies by type: Text (instant), URL (depends on content and nested links), Files (depends on the uploaded file). ## Choose Your Item Type Select the type of item you want to create: Create items by entering text content directly into the platform. Perfect for FAQs, policies, and quick reference materials. Upload documents like PDFs, Word files, and other supported formats. Ideal for manuals, documentation, and comprehensive guides. Import content from web pages and sitemaps. Great for online documentation, product pages, and frequently updated content. ## Draft Management The system automatically saves drafts as you work: ### Auto-Save Features * **Local Storage**: Drafts saved to browser localStorage * **Persist Across Sessions**: Drafts survive browser close * **Separate Drafts**: One draft per item type (Text, File, URL) * **Warning on Navigation**: Alert before leaving with unsaved changes ### Draft Indicators When you return to create an item: * Badge shows **"Continue with saved draft"** * Draft description shows what's ready * One-click resume of previous work ### Draft Lifecycle 1. **Start Creation**: Begin adding an item 2. **Fill Form**: Enter name, content, files, or URLs 3. **Navigate Away**: Draft automatically saved 4. **Return Later**: Draft loads automatically 5. **Complete and Save**: Draft removed after successful creation Use drafts to work on multiple items over time. Your progress is always saved automatically. ## Validation and Error Handling ### Inline Validation The system validates input in real-time: **Text Items:** * Name length (1-100 characters) * Content length (50-5,000 characters) * Whitespace checks **File Items:** * File size (max 21MB) * File format (supported extensions) * File name length (1-100 characters) **URL Items:** * URL format (must be HTTPS) * Domain validation * Media URL detection ### Error Messages Common validation errors: * **"Name is required"**: Name field is empty * **"Name must be 1-100 characters"**: Name too short or long * **"Content must be at least 50 characters"**: Text content too short * **"Content cannot exceed 5,000 characters"**: Text content too long * **"File size exceeds 21MB"**: File too large * **"Invalid URL format"**: URL doesn't start with https\:// * **"Media URLs are not supported"**: URL points to media file ### Toast Notifications Success and error messages appear as toast notifications: * **Success**: "Item created successfully" * **Error**: Specific error message with details * **Processing**: "Item is being processed" ## Storage Quota Management ### Visual Storage Display The system displays: * Current storage usage * Storage limit for your plan * Visual progress indicator * Percentage used ### Quota Enforcement When you reach your storage limit: * **Add buttons disabled**: Cannot create new items * **Clear messaging**: Shows why buttons are disabled * **Upgrade prompt**: Suggests upgrading plan ### Plan Limits | Plan | Storage Limit | | ---------- | ------------- | | Free | 1 MB | | Starter | 5 MB | | Creator | 10 MB | | Pro | 50 MB | | Business | 100 MB | | Enterprise | Custom | Storage limits apply to the total size of all knowledge base items. Delete unused items or upgrade your plan to add more content. ## Next Steps After creating items: 1. **[Monitor Processing Status](./status-lifecycle)** - Track item processing 2. **[Manage Items](./managing-items)** - Organize and filter your knowledge base 3. **[Add to Agents](../single-prompt/configure-settings)** - Use items in your agents 4. **[Review Best Practices](./best-practices)** - Optimize your knowledge base ## Related Documentation Step-by-step guide for creating text items Step-by-step guide for uploading documents Step-by-step guide for importing URLs Learn how to organize and filter your knowledge base Understand processing states and error handling Optimize your knowledge base for best results # File Items Source: https://docs.tryhamsa.com/agents/knowledge-base/creating-items/file-items Upload documents to add to your knowledge base ## Overview File items allow you to upload documents that will be processed and indexed. File upload interface showing drag and drop area and file list File upload interface showing drag and drop area and file list ## When to Use File Items File items are ideal for: * Product manuals and documentation * Technical specifications * Policy documents * Training materials * Comprehensive guides ## Supported File Formats | Format | Extension | Max Size | Processing Time | | -------------------- | --------- | -------- | --------------- | | PDF | `.pdf` | 21 MB | Depends on file | | Word Document | `.docx` | 21 MB | Depends on file | | Word Document Legacy | `.doc` | 21 MB | Depends on file | | Text File | `.txt` | 21 MB | Depends on file | | HTML File | `.html` | 21 MB | Depends on file | | EPUB | `.epub` | 21 MB | Depends on file | ## Requirements | Field | Requirement | Validation | | ----------------- | ----------- | ------------------------------------------------------------------------ | | **Document Name** | Required | Auto-filled from filename, editable (1-100 chars), shows character count | | **Files** | Required | At least one file, max 21MB per file | ## Step-by-Step Process 1. **Navigate to Knowledge Base** * Go to the [Knowledge Base section](https://agents.tryhamsa.com/app/knowledge-base) * Click **"Add Document"** button 2. **Upload Files** * The "Add Document" modal opens * **Drag and Drop**: Drag files into the upload area (shows "Drop files to upload") * **Click to Browse**: Click the upload area to select files from your computer * **Supported formats**: PDF, DOCX, DOC, TXT, HTML, EPUB * **Max size**: 21 MB per file 3. **Review Uploaded File** * Once uploaded, the file appears with: * File icon and type indicator * Filename * File size * Remove button (X icon) to delete the file 4. **Edit Document Name** * Document name is auto-filled from the filename * Edit the name in the "Document Name" field (1-100 characters) * Character counter shows current length (e.g., "27/100") * File extension (e.g., ".docx") is displayed next to the name field 5. **Save or Cancel** * Click **"Save"** to create the knowledge base item * Click **"Cancel"** to close without saving * Click **"Clear"** to remove the uploaded file and start over * Processing begins automatically after saving Each uploaded file becomes a separate knowledge base item. You can upload multiple files in one session, but they're processed individually. ## File Upload Best Practices **File Preparation:** * Ensure files are not password-protected * Verify files open correctly on your computer * Check file size (max 21MB per file) * Use clear, descriptive filenames **Content Quality:** * Use well-formatted documents with clear headings * Ensure text is extractable (not just images) * Avoid complex layouts that may not parse well * Include relevant metadata in filenames **Example Filenames:** ``` Good: "Product_Manual_2024.pdf" Good: "Return_Policy_Q1_2024.docx" Bad: "doc1.pdf" Bad: "file_final_final_v2.pdf" ``` ## File Processing After upload, files go through these stages: 1. **Upload**: File is uploaded to the server 2. **Reading**: Content is extracted from the file 3. **Ingestion**: Content is indexed for retrieval 4. **PROCESSED**: Item is ready for use (shown as "completed" in dashboard) If a file fails at any stage, you'll see an error status. Common issues include password-protected files, corrupted files, or unsupported formats. ## Related Documentation Overview of all item creation types Learn how to create text content Learn how to import web content Understand file processing states # Text Items Source: https://docs.tryhamsa.com/agents/knowledge-base/creating-items/text-items Create text items by entering content directly into the platform ## Overview Text items allow you to add free-form text content directly to your knowledge base. Create text item form showing name and content fields Create text item form showing name and content fields ## When to Use Text Items Text items are ideal for: * Quick FAQs and policies * Company information * Product descriptions * Short reference materials * Content that changes frequently ## Requirements | Field | Requirement | Validation | | ---------------- | ----------- | -------------------------------------------------------------------- | | **Text Name** | Required | 1-100 characters, not whitespace only | | **Text Content** | Required | Minimum 50 characters, maximum 5,000 characters, not whitespace only | ## Step-by-Step Process 1. **Navigate to Knowledge Base** * Go to the [Knowledge Base section](https://agents.tryhamsa.com/app/knowledge-base) in your dashboard * Click **"Add Free Text"** button 2. **Enter Item Details** * **Text Name**: Enter a descriptive name (1-100 characters) * Example: "Return Policy 2024" * Example: "Business Hours - Customer Service" * **Text Content**: Enter or paste your text content * Minimum: 50 characters * Maximum: 5,000 characters * Must contain actual content (not just whitespace) 3. **Validate and Save** * Review your content * Click **"Save"** button * Processing starts automatically Text items are processed instantly. Ensure your content is accurate before saving, as you'll need to edit the title or delete and recreate to change content. ## Text Item Examples **Example 1: Return Policy** ``` Name: "Return Policy - Electronics" Content: "We offer a 30-day return policy on all electronics. Items must be in original condition with all packaging and accessories. Refunds are processed within 5-7 business days after we receive the return. Shipping costs are non-refundable unless the item was defective." ``` **Example 2: Business Hours** ``` Name: "Customer Service Hours" Content: "Our customer service is available: Monday-Friday: 9 AM - 6 PM EST Saturday: 10 AM - 4 PM EST Sunday: Closed Holiday hours may vary. Check our website for holiday schedules." ``` **Example 3: Product Specifications** ``` Name: "Product X - Technical Specs" Content: "Product X features: - Dimensions: 10" x 8" x 2" - Weight: 1.5 lbs - Power: 120V AC, 60Hz - Warranty: 2 years - Compatibility: Windows 10+, macOS 11+, Linux" ``` ## Text Limits * **Minimum**: 50 characters * **Maximum**: 5,000 characters For longer content, consider breaking it into multiple focused text items rather than one large item. This improves retrieval accuracy. ## Related Documentation Overview of all item creation types Learn how to upload documents Learn how to import web content Organize and manage your knowledge base # URL Items Source: https://docs.tryhamsa.com/agents/knowledge-base/creating-items/url-items Import web content from URLs and sitemaps ## Overview URL items allow you to import content from web pages. URL creation form showing name and URL input fields URL creation form showing name and URL input fields ## When to Use URL Items URL items are ideal for: * Product pages * Online documentation * Blog articles * Support articles * Public knowledge bases * Frequently updated content ## Requirements | Field | Requirement | Validation | | -------------- | ----------- | ---------------------------------------------- | | **Link Name** | Required | 1-100 characters | | **Link (URL)** | Required | Valid HTTPS URL, valid domain, not a media URL | ## URL Validation Rules **Required:** * Must start with `https://` * Must be a valid URL format * Must have a valid domain name or IP address **Not Supported:** * HTTP URLs (must use HTTPS) * Media file URLs (`.mp3`, `.mp4`, `.wav`, `.jpg`, `.png`, etc.) * Download links to media files * URLs requiring authentication ## Single URL Creation **Step-by-Step Process:** 1. **Navigate to Knowledge Base** * Go to the [Knowledge Base section](https://agents.tryhamsa.com/app/knowledge-base) * Click **"Add URL"** button 2. **Enter URL Details** * The "Add URL" modal opens * **Link Name**: Enter a descriptive name (1-100 characters) * Example: "Product Catalog - Q1 2024" * Example: "API Documentation v2" * **Link (URL)**: Enter the HTTPS URL * Example: `https://www.example.com/products` * Example: `https://docs.example.com/api/getting-started` 3. **Save and Discover Links** * Click **"Save"** button * Button text changes to **"Processing..."** * System automatically discovers the sitemap and crawls for links * The **"Select URLs from Sitemap"** modal appears automatically 4. **Select URLs from Sitemap** * Review the discovered URLs in the modal * **Search URLs**: Use the search bar to find specific URLs * **Add Custom URL**: Click the "Add custom URL..." field to manually add additional URLs * **Select URLs**: * Check individual URLs to select them * Use "Invert Selection" to toggle all selections * Selection counter shows "X/100 items selected" (maximum 100 URLs per item) 5. **Save and Process** * Click **"Save"** button in the sitemap selection modal * Item is saved and processing begins * Processing depends on the content and nested links The system fetches web page content at the time of creation. If the web page updates later, you'll need to delete and re-add the URL to get fresh content. ## Sitemap Selection Modal After entering a URL and clicking "Save", the system automatically discovers and displays available links: Select URLs from Sitemap modal showing URL list, search bar, selection checkboxes, and action buttons Select URLs from Sitemap modal showing URL list, search bar, selection checkboxes, and action buttons **Modal Features:** * **Search URLs**: Use the search bar to filter and find specific URLs from the discovered links * **Add Custom URL**: Manually add additional URLs that aren't in the sitemap using the "Add custom URL..." field * **URL List**: * Each URL shows the full URL in green text * Display title and description for each URL * Checkboxes to select/deselect URLs * External link icon next to each URL * **Selection Counter**: Shows "X/100 items selected" at the bottom (maximum 100 URLs per item) * **Actions**: * **Invert Selection**: Toggle all current selections * **Clear**: Remove all selections * **Cancel**: Close without saving * **Save**: Save selected URLs and begin processing Sitemap fetching uses Server-Sent Events (SSE) for real-time progress updates. If the sitemap endpoint is unavailable, the system falls back to a legacy endpoint. ## Sitemap Behavior **How It Works:** * System locates sitemap.xml at common paths * Parses sitemap to extract URLs * Groups URLs by domain * Streams results in real-time **Limitations:** * Maximum 100 URLs per knowledge base item * Large sitemaps may take time to process * Some sites may block scraping * Requires publicly accessible sitemap If a website blocks scraping or requires authentication, the URL will fail to process. Use public, accessible pages only. ## URL Processing Details Each URL in a URL item includes: * **URL**: The web page address * **Scraping Status**: Current processing state * **Processing State**: Detailed status information * **Error Message**: Failure reason if processing fails * **Failure Reason**: Specific error details ## URL Item Examples **Example 1: Single Product Page** ``` Name: "Product X - Specifications" URL: https://www.example.com/products/product-x ``` **Example 2: Documentation Section** ``` Name: "API Getting Started Guide" URL: https://docs.example.com/api/getting-started ``` **Example 3: Multiple Pages via Sitemap** ``` Base URL: https://docs.example.com Fetched URLs: - https://docs.example.com/api/authentication - https://docs.example.com/api/endpoints - https://docs.example.com/api/errors - ... (up to 100 URLs) ``` ## Related Documentation Overview of all item creation types Learn how to create text content Learn how to upload documents Understand URL processing states # Overview Source: https://docs.tryhamsa.com/agents/knowledge-base/introduction Comprehensive content management for Voice Agents with text, file, and URL support ## Overview The Knowledge Base feature provides comprehensive content management for Voice Agents in the Hamsa platform. It enables you to store, organize, and manage information that your AI agents can reference during conversations, ensuring accurate and contextually relevant responses. Knowledge Base overview showing list of items with different types and statuses Knowledge Base overview showing list of items with different types and statuses **Knowledge Base enables your agents to:** * Answer questions using your company's documentation * Reference product information, policies, and procedures * Access up-to-date information from web sources * Provide accurate responses based on your content ## What is a Knowledge Base? A Knowledge Base is a centralized repository of information that your Voice Agents can access during conversations. Each knowledge base item contains content that helps agents answer questions accurately and provide relevant information to callers. ### Key Capabilities **Content Management** * Create items from text, files, or URLs * Organize and categorize your knowledge * Track usage across multiple agents * Monitor processing status in real-time **Flexible Content Types** * **Text Items**: Direct text input for quick content * **File Items**: Upload documents (PDF, DOCX, TXT, HTML, EPUB) * **URL Items**: Import content from web pages and sitemaps **Intelligent Processing** * Automatic content extraction and indexing * Real-time status tracking * Error handling and retry mechanisms * Storage quota management **Agent Integration** * Activate or deactivate items per agent * Track which agents use which items * Prevent deletion of items in use * Visual usage indicators ## Knowledge Base Item Types The system supports three types of knowledge base items, each suited for different use cases: ### Text Items Free-form text content entered directly into the platform. **Best for:** * Quick FAQs and policies * Company information * Product descriptions * Short reference materials **Specifications:** * Minimum: 50 characters * Maximum: 5,000 characters * Processing: Instant * Format: Plain text ### File Items Document files uploaded from your computer. **Supported formats:** * PDF (`.pdf`) * Word Documents (`.docx`) * Word Documents Legacy (`.doc`) * Text Files (`.txt`) * HTML Files (`.html`) * EPUB (`.epub`) **Best for:** * Product manuals * Technical documentation * Policy documents * Training materials **Specifications:** * Multiple files: Upload multiple files at once * Processing: Depends on the uploaded file ### URL Items Web content imported from websites. **Best for:** * Product pages * Online documentation * Blog articles * Support articles * Public knowledge bases **Specifications:** * HTTPS URLs only * Single URL or multiple URLs via sitemap * Maximum: 100 URLs per item * Processing: Depends on the content and nested links ## Knowledge Base Status Lifecycle Knowledge base items move through various processing states: ### Processing States | Status | Description | Next Action | | --------------------------- | -------------------------------- | ------------------------- | | **PROCESSING** | Item is being processed | Wait for PROCESSED status | | **PROCESSED** | Successfully processed and ready | Available for use | | **FAILED** | Fatal processing error | Review error and retry | | **COMPLETED\_WITH\_ERRORS** | Completed with some errors | Review and fix issues | | **UPLOAD\_FAILURE** | File upload failed | Check file and retry | | **READING\_FAILURE** | Failed to read file | Verify file format | | **INGESTION\_FAILURE** | Failed to ingest content | Check content quality | Items reach a terminal state automatically. Failed items cannot be used in agents. ## Storage Limits by Plan Knowledge Base storage limits vary by subscription tier: Storage limits table showing plan tiers and their corresponding storage limits Storage limits table showing plan tiers and their corresponding storage limits You can view your current plan's storage limits and compare all plans on the [billing page](https://agents.tryhamsa.com/app/billing). | Plan | Storage Limit | | -------------- | ------------- | | **Free** | 1 MB | | **Starter** | 5 MB | | **Creator** | 10 MB | | **Pro** | 50 MB | | **Business** | 100 MB | | **Enterprise** | Custom | Storage limits apply to the total size of all knowledge base items in your workspace. The system displays your current usage and disables add buttons when you reach your limit. ## Key Features ### Automatic Processing Items are processed automatically upon creation: * Text items: Instant processing * File items: Automatic extraction and indexing * URL items: Automatic scraping and content extraction ### Status Tracking Real-time status updates show: * Current processing state * Error messages for failed items * Completion indicators * Processing progress ### Agent Integration * **Activation Control**: Enable or disable items per agent * **Usage Tracking**: See which agents use which items * **Deletion Protection**: Prevent deletion of items in use * **Visual Indicators**: Clear usage status in the list view ### Search and Filtering Powerful search and filtering capabilities: * Search by item name * Filter by type (Text, File, URL) * Filter by status * Filter by file extension * Filter by usage (used/not used) ### Sorting Options Sort items by: * Created date (newest/oldest) * Word count (most/fewest) * File size (largest/smallest) ## Prerequisites Before creating knowledge base items, ensure you have: * An active project selected * Appropriate permissions to manage knowledge base items * Available storage quota (check your plan limits) ## Common Use Cases ### Customer Support **Scenario**: Answer common customer questions **Setup**: * Create Text items for FAQs * Upload policy documents as File items * Add support article URLs **Result**: Agents can answer questions about returns, shipping, policies, etc. ### Product Information **Scenario**: Provide detailed product information **Setup**: * Upload product manuals as PDFs * Add product page URLs * Create Text items for specifications **Result**: Agents can provide accurate product details and specifications ### Technical Documentation **Scenario**: Reference technical documentation **Setup**: * Upload technical manuals * Add API documentation URLs * Create Text items for quick references **Result**: Agents can help with technical questions and troubleshooting ### Company Policies **Scenario**: Enforce company policies and procedures **Setup**: * Create Text items for key policies * Upload employee handbooks * Add policy page URLs **Result**: Agents can reference and explain company policies accurately ## What's Next? * **[Quick Start](./quick-start)** - Get started in 4 simple steps * **[Creating Knowledge Base Items](./creating-items)** - Learn how to create text, file, and URL items * **[Managing Knowledge Base](./managing-items)** - Organize, search, and filter your items * **[Status and Lifecycle](./status-lifecycle)** - Understand processing states and error handling * **[Best Practices](./best-practices)** - Optimize your knowledge base for best results ## Related Documentation Get started with Knowledge Base in 4 simple steps Learn how to use knowledge base in single prompt agents Configure knowledge base in flow-based agents General knowledge base feature documentation # Managing Items Source: https://docs.tryhamsa.com/agents/knowledge-base/managing-items Organize, search, filter, and manage your items ## Overview The Knowledge Base list view provides comprehensive management capabilities: * **Search** items by name * **Filter** by type, status, extension, usage, and active state * **Sort** by date, word count, or file size * **Edit** item titles * **Delete** items (with protection for items in use) * **Download** items (Text and File types) * **View** item details in drawer All management actions are available from the Knowledge Base list view. Click any item to open the details drawer for more information. ## List View Overview The Knowledge Base list displays all items in a table format with the following columns: Knowledge Base list view showing table with items, filters, and search Knowledge Base list view showing table with items, filters, and search ### Displayed Information | Column | Description | Available For | | ---------------- | --------------------------- | ------------- | | **Name** | Item name/title | All types | | **Type** | TEXT, FILE, or URL | All types | | **Status** | Processing state | All types | | **Created Date** | When item was created | All types | | **Word Count** | Number of words in content | All types | | **File Size** | Size of uploaded file | File only | | **Extension** | File extension | File only | | **Used** | Indicator if used in agents | All types | ### Visual Indicators **Status Colors:** * 🟡 **PROCESSING**: Item is being processed (yellow indicator) * 🟢 **PROCESSED**: Item is ready for use (green indicator, shown as "completed" in dashboard) * 🔴 **FAILED**: Item processing failed (red indicator) * 🟠 **COMPLETED\_WITH\_ERRORS**: Item processed with warnings (orange indicator) **API vs Dashboard Terminology:** The API returns status values like `PROCESSED`, `PROCESSING`, `FAILED`, etc. In the dashboard UI, `PROCESSED` is displayed as "completed" for better user experience. API users should always use the API status values (`PROCESSED`) when working with the API endpoints. **Usage Indicator:** * ✓ **Used**: Item is assigned to one or more agents * — **Not Used**: Item is not currently used ## Search Functionality ### Searching by Name The search bar allows real-time searching by item name: 1. **Enter Search Query** * Type in the search bar at the top * Search is case-insensitive * Searches item names only 2. **View Results** * Results update as you type * Matching items are highlighted * Non-matching items are hidden 3. **Clear Search** * Click the X button or clear the search field * All items are shown again **Example Searches:** ``` "return policy" → Finds items with "return policy" in name "FAQ" → Finds all FAQ-related items "2024" → Finds items with "2024" in name ``` Use descriptive names when creating items to make searching easier. Include keywords that you'll search for later. ## Filtering Options The Knowledge Base supports multiple filter types that can be combined: ### Filter by Type Filter items by their content type: **Options:** * **All Types** (default) * **TEXT** only * **FILE** only * **URL** only **Use Case:** * Find all text items for quick review * Locate all uploaded documents * View only URL-based items ### Filter by Status Filter items by their processing status: **Options:** * **All Statuses** (default) * **PROCESSED** - Ready for use (shown as "completed" in dashboard, returned as `PROCESSED` from API) * **PROCESSING** - Currently being processed * **FAILED** - Processing failed * **COMPLETED\_WITH\_ERRORS** - Processed with warnings * **UPLOAD\_FAILURE** - Upload failed * **READING\_FAILURE** - File reading failed * **INGESTION\_FAILURE** - Content ingestion failed **Use Case:** * Find items that need attention (failed statuses) * See which items are still processing * View only ready-to-use items When using the API, filter by `PROCESSED` status. The dashboard displays this as "completed" for better user experience, but the API always returns `PROCESSED`. ### Filter by Extension Filter file items by their file extension: **Options:** * **All Extensions** (default) * **PDF** (`.pdf`) * **Word** (`.docx`) * **Word Legacy** (`.doc`) * **Text** (`.txt`) * **HTML** (`.html`) * **EPUB** (`.epub`) Extension filter only works with FILE type items. If you select TEXT or URL types along with an extension filter, you'll see a conflict error. ### Filter by Usage Filter items by whether they're used in agents: **Options:** * **All Items** (default) * **Used in agents** - Assigned to one or more agents * **Not used in agents** - Not currently assigned **Use Case:** * Identify unused items for deletion * Find items currently in use * Review which items need to be assigned ### Filter Conflicts **Type + Extension Conflict:** If you select both a type filter (TEXT or URL) and an extension filter: * Error message is displayed * API calls are blocked * Clear one of the conflicting filters **Resolution:** * Select FILE type only when using extension filter * Remove TEXT/URL from type filter * Clear extension filter when filtering by TEXT/URL ## Sorting Options Sort items by different criteria: ### Sort by Created Date **Options:** * **Newest First** (default) * **Oldest First** **Use Case:** * Find recently created items * Review oldest items for cleanup * Track item creation timeline ### Sort by Word Count **Options:** * **Most Words First** * **Fewest Words First** **Use Case:** * Identify comprehensive items * Find short items that may need expansion * Review content depth ### Sort by File Size **Options:** * **Largest First** * **Smallest First** **Available For:** File items only **Use Case:** * Identify large files consuming storage * Find small files for review * Monitor storage usage ## Item Actions Menu Each item has an actions menu (⋮) with the following options: ### Edit Title Change the item's display name: 1. Click the **Actions** menu (⋮) on the item 2. Select **"Edit Title"** 3. Enter new name (1-100 characters) 4. Click **"Save Changes"** Editing the title doesn't affect the item's content, only its display name. Content cannot be edited after creation. ### Download Item Download the original content: **Text Items:** * Downloads as `.txt` file * Contains the text content **File Items:** * Downloads original file in its format * Preserves original file extension **URL Items:** * Downloads extracted content as `.txt` file * Contains scraped web content **Process:** 1. Click the **Actions** menu (⋮) 2. Select **"Download"** 3. File downloads to your computer ### Delete Item Remove an item from your knowledge base: **Process:** 1. Click the **Actions** menu (⋮) 2. Select **"Delete"** 3. Type `DELETE` to confirm 4. Click **"Confirm Deletion"** **Deletion Protection:** Items used in agents cannot be deleted. You must first remove the item from all agents that use it. This prevents accidentally breaking agent knowledge. **If Item is in Use:** * Delete action is disabled or shows warning * Message indicates which agents use the item * Remove from agents first, then delete ### Activate/Deactivate Control item availability without deleting: **Active:** * Item is available for agents to use * Appears in agent knowledge base selection * Can be assigned to agents **Inactive:** * Item is hidden from agent selection * Cannot be assigned to new agents * Still exists in knowledge base * Can be reactivated later **Toggle Process:** 1. Click the **Actions** menu (⋮) 2. Select **"Activate"** or **"Deactivate"** 3. Status updates immediately Use Inactive status to temporarily hide outdated information without losing it permanently. This is useful for seasonal content or content under review. ## Item Details Drawer Click any item to open the details drawer: Knowledge Base item details drawer showing item information and content Knowledge Base item details drawer showing item information and content ### Drawer Sections **Basic Information:** * Item name * Type (TEXT, FILE, URL) * Status with detailed information * Created date * Last updated date **Usage Indicator:** * Shows if item is used in agents * Lists which agents use the item (if any) **Type-Specific Information:** **File Items:** * File size * File extension * Download button * Original filename **Text Items:** * Full text content * Word count * Character count * Download button **URL Items:** * Grouped URLs by domain * Per-URL status * Scraping status for each URL * Error messages for failed URLs * Delete individual URLs * Add more URLs (up to 100 total) ### URL Item Management In the URL item drawer, you can: **View URLs:** * See all URLs in the item * Grouped by domain for easy navigation * Status indicator for each URL **Delete URLs:** * Remove individual URLs from the item * Useful for cleaning up failed URLs * Maintains other URLs in the item **Add URLs:** * Add more URLs to existing item * Maximum 100 URLs per item * Same validation as creating new URL items ## Bulk Operations While bulk operations aren't currently supported, you can: **Efficient Management:** * Use filters to narrow down items * Sort to group similar items * Use search to find specific items * Delete multiple items individually **Best Practices:** * Filter by "Not used" to find items for cleanup * Sort by "Oldest First" to review old items * Use status filters to find failed items ## Storage Management ### Viewing Storage Usage The system displays: * Current storage usage * Storage limit for your plan * Visual progress indicator * Percentage used ### Managing Storage **When Approaching Limit:** * Review and delete unused items * Deactivate items instead of deleting * Consider upgrading your plan **Storage Optimization:** * Delete failed items that can't be fixed * Remove duplicate items * Archive old items you no longer need * Compress large files before uploading ## Troubleshooting ### Items Not Appearing **Possible Causes:** * Filters are applied (check filter settings) * Search query is too specific * Item is inactive * Item failed to process **Solutions:** * Clear all filters * Clear search query * Check item status * Verify item is active ### Cannot Delete Item **Possible Causes:** * Item is used in one or more agents * Item is currently processing * Network error **Solutions:** * Remove item from all agents first * Wait for processing to complete * Check network connection and retry ### Filter Not Working **Possible Causes:** * Filter conflict (Type + Extension) * No items match filter criteria * Filter not applied correctly **Solutions:** * Check for filter conflicts * Verify items exist that match criteria * Clear and reapply filters ## Next Steps * **[Status Lifecycle](./status-lifecycle)** - Understand processing states * **[Creating Items](./creating-items)** - Learn how to create new items * **[Best Practices](./best-practices)** - Optimize your knowledge base ## Related Documentation Learn how to create knowledge base items Understand processing states and errors Optimize your knowledge base management # Quick Start Source: https://docs.tryhamsa.com/agents/knowledge-base/quick-start Get started with Knowledge Base in 4 simple steps ## Overview Get up and running with Knowledge Base quickly. Follow these steps to create your first knowledge base item and add it to your agents. ## Prerequisites Before getting started, ensure you have: * An active project selected * Appropriate permissions to manage knowledge base items * Available storage quota (check your plan limits) ## Quick Start Steps 1. **Navigate to Knowledge Base** * Go to the [Knowledge Base section](https://agents.tryhamsa.com/app/knowledge-base) in your dashboard * Click the appropriate button based on your content type: * **"Add Free Text"** for text content * **"Add Document"** for file uploads * **"Add URL"** for web content Knowledge Base add buttons showing Add URL, Add Document, and Add Free Text options Knowledge Base add buttons showing Add URL, Add Document, and Add Free Text options 2. **Follow the Creation Wizard** * Complete the form for your chosen content type 3. **Monitor Processing** * Watch the status indicator as your item processes * Wait for "PROCESSED" status (shown as "completed" in dashboard) before using in agents 4. **Add to Agents** * Open your agent configuration * Navigate to Knowledge Base section Global Settings panel showing Knowledge Base section with Manage button Global Settings panel showing Knowledge Base section with Manage button * Click **"Manage"** to open the item selection modal * Select the items you want to use Select Knowledge Base Items modal showing search bar, item list with types and word counts, and selection buttons Select Knowledge Base Items modal showing search bar, item list with types and word counts, and selection buttons * Click **"Done"** to save your selection ## Next Steps Now that you've created your first knowledge base item: * **[Creating Items](./creating-items)** - Learn detailed steps for creating different item types * **[Managing Items](./managing-items)** - Organize, search, and filter your items * **[Status Lifecycle](./status-lifecycle)** - Understand processing states and troubleshooting * **[Best Practices](./best-practices)** - Optimize your knowledge base for best results ## Related Documentation Learn more about Knowledge Base features and capabilities Detailed guide on creating text, file, and URL items How to organize and manage your knowledge base # Status Lifecycle and Processing Source: https://docs.tryhamsa.com/agents/knowledge-base/status-lifecycle Understand item processing states, status tracking, and error handling ## Overview Knowledge base items automatically progress through processing states until they reach a terminal state. Understanding these states helps you monitor item creation and troubleshoot issues. Processing happens automatically after item creation. You don't need to manually trigger processing - the system handles it for you. ## Processing States Knowledge base items move through the following states: Status lifecycle diagram showing progression from processing to terminal states Status lifecycle diagram showing progression from processing to terminal states ### Terminal States These are final states that items reach after processing: | Status | Description | Action Required | | --------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------- | | **PROCESSED** | Item processed successfully and ready (shown as "completed" in dashboard, returned as `PROCESSED` from API) | None - ready to use | | **FAILED** | Fatal processing error | Review error and retry | | **COMPLETED\_WITH\_ERRORS** | Processing completed with some errors | Review warnings | | **UPLOAD\_FAILURE** | File upload failed | Check file and retry | | **READING\_FAILURE** | Failed to read file | Verify file format | | **INGESTION\_FAILURE** | Failed to ingest content | Check content quality | ### Intermediate States | Status | Description | Duration | | --------------------- | ----------------------- | -------------- | | **PROCESSING** (null) | Item is being processed | Varies by type | ## Status by Item Type ### Text Items **Processing Flow:** 1. **PROCESSING** → **PROCESSED** (instant) **Common Issues:** * None (text items process instantly) ### File Items **Processing Flow:** 1. **PROCESSING** (Upload) → **PROCESSING** (Reading) → **PROCESSING** (Ingestion) → **PROCESSED** **Duration:** * Depends on the uploaded file (varies by size and complexity) **Common Failure Points:** * **UPLOAD\_FAILURE**: Network issues, file too large * **READING\_FAILURE**: Corrupted file, unsupported format, password-protected * **INGESTION\_FAILURE**: Content extraction issues, complex formatting ### URL Items **Processing Flow:** 1. **PROCESSING** (Scraping) → **PROCESSED** or **FAILED** **Duration:** * Depends on the content and nested links (varies by page complexity and number of links) **Common Failure Points:** * **FAILED**: URL not accessible, requires authentication, blocked by site * **COMPLETED\_WITH\_ERRORS**: Some URLs failed, others succeeded ## Status Details ### PROCESSED **Meaning:** Item has been successfully processed and is ready for use. **Characteristics:** * ✅ Green status indicator * Available for selection in agents * Content is indexed and searchable * No action required **What Happens:** * Content is extracted and indexed * Item appears in knowledge base list * Can be assigned to agents * Ready for retrieval during conversations ### PROCESSING **Meaning:** Item is currently being processed. **Characteristics:** * 🟡 Yellow status indicator * Not yet available for use * Processing in progress * Wait for PROCESSED status (shown as "completed" in dashboard) **What Happens:** * System is extracting content * Content is being indexed * Processing stages vary by type **For File Items:** 1. **Upload Stage**: File is being uploaded to server 2. **Reading Stage**: Content is being extracted from file 3. **Ingestion Stage**: Content is being indexed for retrieval **For URL Items:** 1. **Scraping Stage**: Web page content is being fetched 2. **Extraction Stage**: Text content is being extracted 3. **Indexing Stage**: Content is being indexed Processing times vary based on item size and complexity. Large files or complex web pages take longer to process. ### FAILED **Meaning:** Fatal error occurred during processing. **Characteristics:** * 🔴 Red status indicator * Item cannot be used * Error message displayed * Action required **Common Causes:** * **URL Items**: Site blocked scraping, requires authentication, URL not accessible * **File Items**: Corrupted file, unsupported format * **Network Issues**: Connection timeout, server error **Resolution:** 1. Review error message in item details 2. Check item content/source 3. Fix the issue (if possible) 4. Delete failed item and recreate Failed items cannot be used in agents. You must fix the issue and recreate the item. ### COMPLETED\_WITH\_ERRORS **Meaning:** Processing completed but some parts failed. **Characteristics:** * 🟠 Orange status indicator * Partially usable * Some content may be missing * Review recommended **Common Scenarios:** * **URL Items**: Some URLs in a multi-URL item failed * **File Items**: Some pages/sections couldn't be extracted **Resolution:** 1. Review item details for specific errors 2. Check which parts failed 3. Decide if item is usable as-is 4. Delete and recreate if too many errors ### UPLOAD\_FAILURE **Meaning:** File upload to server failed. **Characteristics:** * 🔴 Red status indicator * File never reached server * Upload stage failed **Common Causes:** * File size exceeds 21MB limit * Network connection interrupted * Server temporarily unavailable * File corruption during upload **Resolution:** 1. Check file size (must be \< 21MB) 2. Verify network connection 3. Try uploading again 4. Compress file if too large ### READING\_FAILURE **Meaning:** System couldn't read/extract content from file. **Characteristics:** * 🔴 Red status indicator * File uploaded but content couldn't be extracted * Reading stage failed **Common Causes:** * File is password-protected * File is corrupted * Unsupported file format * File contains only images (no extractable text) * Complex formatting that parser can't handle **Resolution:** 1. Remove password protection 2. Verify file opens correctly on your computer 3. Ensure file is in supported format 4. Save file in simpler format (e.g., .txt) 5. Ensure file contains extractable text ### INGESTION\_FAILURE **Meaning:** Content extracted but couldn't be indexed. **Characteristics:** * 🔴 Red status indicator * Content read but indexing failed * Ingestion stage failed **Common Causes:** * Content quality issues * Extremely complex formatting * Content too large for processing * Server-side processing error **Resolution:** 1. Check content quality 2. Simplify file formatting 3. Break into smaller items 4. Try recreating with different format ## Status Tracking ### Real-Time Updates Status updates happen in real-time: * Status changes automatically * No page refresh needed * Visual indicators update immediately ### Status Indicators **Visual Colors:** * 🟢 **Green**: Success (PROCESSED) * 🟡 **Yellow**: In Progress (PROCESSING) * 🔴 **Red**: Failed (FAILED, UPLOAD\_FAILURE, READING\_FAILURE, INGESTION\_FAILURE) * 🟠 **Orange**: Warning (COMPLETED\_WITH\_ERRORS) ### Status in List View The list view shows: * Current status with color indicator * Status text label * Quick visual reference ### Status in Details Drawer The details drawer shows: * Current status * Detailed status information * Error messages (if failed) * Processing history (if available) ## Error Handling ### Error Messages When an item fails, you'll see: * **Status**: Failed state (FAILED, UPLOAD\_FAILURE, etc.) * **Error Message**: Brief description of the issue * **Failure Reason**: Detailed explanation (in drawer) ### Common Error Messages **File Upload Errors:** * "File size exceeds 21MB limit" * "Upload failed. Please try again." * "Network error during upload" **File Reading Errors:** * "File is password-protected" * "Could not read file format" * "File appears to be corrupted" * "No extractable text found in file" **URL Scraping Errors:** * "URL is not accessible" * "Site requires authentication" * "Scraping blocked by website" * "Invalid URL format" * "Media URL not supported" **Content Ingestion Errors:** * "Content could not be indexed" * "Processing timeout" * "Content format not supported" ### Error Resolution **Step 1: Review Error** * Open item details drawer * Read error message and failure reason * Understand what went wrong **Step 2: Identify Cause** * Check item source/content * Verify requirements are met * Test item independently (open file, visit URL) **Step 3: Fix Issue** * Address the root cause * Modify content if needed * Ensure item meets requirements **Step 4: Retry** * Delete failed item * Recreate with fixed content * Monitor processing status ## Monitoring Processing ### During Creation **What to Watch:** * Status changes from PROCESSING to terminal state * Processing time (varies by type and size) * Any error messages **Expected Behavior:** * Text: Instant processing * URL: Depends on content and nested links * File: Depends on the uploaded file ### After Creation **Check Status:** * View list to see all item statuses * Filter by status to find issues * Open details for more information **Regular Monitoring:** * Review failed items weekly * Check processing times * Monitor for unusual patterns ## Troubleshooting ### Item Stuck in PROCESSING **Possible Causes:** * Very large file taking time * Network issues * Server processing delay **Solutions:** * Wait longer (up to 5 minutes for large files) * Check network connection * Refresh page to see updated status * Contact support if stuck > 10 minutes ### Multiple Failures **Possible Causes:** * Systematic issue (network, server) * Content quality problems * Format incompatibility **Solutions:** * Check system status * Review content quality * Try different format * Contact support if persistent ### Inconsistent Status **Possible Causes:** * Page not refreshed * Cache issues * Real-time update delay **Solutions:** * Refresh page * Clear browser cache * Wait a few seconds for updates ## Next Steps * **[Managing Items](./managing-items)** - Organize and filter your items * **[Creating Items](./creating-items)** - Learn how to create items properly * **[Best Practices](./best-practices)** - Optimize your knowledge base ## Related Documentation Learn how to create items that process successfully Filter and manage items by status Avoid common processing issues # Best Practices Source: https://docs.tryhamsa.com/agents/phone-numbers/best-practices Guidance for managing phone numbers effectively Engineer-validated best practices for phone numbers will be added here over time. ## Related Documentation Overview of Phone Numbers features Add and configure phone numbers Learn how to place outbound calls Use phone numbers for batch calls # Overview Source: https://docs.tryhamsa.com/agents/phone-numbers/introduction Comprehensive phone number management with multi-provider support and voice agent integration ## Overview The Phone Numbers feature provides comprehensive management of telephony resources in the Hamsa platform. It enables you to add, configure, and manage phone numbers from multiple providers, assign them to Voice Agents, and make outbound calls. **Phone Numbers enable you to:** * Add phone numbers from multiple providers (Twilio, SIP Trunk) * Assign phone numbers to Voice Agents for inbound calls * Make outbound calls using your Voice Agents * Configure SIP trunk connections for enterprise telephony * Manage phone number lifecycle and assignments ## What are Phone Numbers? Phone Numbers are telephony resources that connect your Voice Agents to the outside world. Each phone number acts as an endpoint that can receive inbound calls and place outbound calls using your configured Voice Agents. ### Key Capabilities **Multi-Provider Support** * Support for multiple telephony providers * Twilio integration with account credentials * SIP Trunk support for enterprise telephony * Provider-specific configuration options * Easy provider switching and management **Voice Agent Integration** * Assign phone numbers to Voice Agents * One-to-one agent assignment * Automatic call routing to assigned agents * Reassignment with validation * Unassign to make numbers available **Outbound Calling** * Make test calls from the dashboard * Pass custom parameters to agents * Configure webhooks for call events * Real-time call initiation * Support for dynamic variables **Batch Calls** * Use phone numbers as "From Number" for batch calls * Execute bulk calls to multiple recipients * Schedule batch calls for specific times * Track individual call statuses per recipient * Manage batch call execution (pause, resume, retry, cancel) **SIP Trunk Configuration** * Full SIP trunk support for enterprises * Inbound and outbound SIP configuration * Custom SIP headers support * Multiple transport types (TCP, UDP) * SIP connection testing before deployment * Authentication support (username/password) ## Supported Providers The platform supports multiple telephony providers, each with specific capabilities: ### Twilio Industry-leading cloud communications platform. **Features:** * Global phone number availability * Reliable call quality * Enterprise-grade infrastructure * Wide geographic coverage **Requirements:** * Twilio Account SID * Twilio Auth Token * Phone number from your Twilio account **Best for:** * Standard voice applications * Global deployments * Reliable cloud telephony ### SIP Trunk Session Initiation Protocol trunking for enterprise telephony. **Features:** * Direct carrier connectivity * Custom SIP configurations * Inbound and outbound support * Transport protocol flexibility (TCP, UDP) * Custom header support * Authentication options **Requirements:** * SIP trunk address (IP or domain) * Phone number for identification * Transport type selection * Optional: SIP credentials (username/password) * Optional: Custom headers for routing **Best for:** * Enterprise deployments * Custom telephony infrastructure * Direct carrier connections * Advanced routing requirements **Configuration Options:** *Inbound:* * Origination URI (SIP over TCP/UDP) * Automatic Hamsa webhook configuration *Outbound:* * Destination address (IP or domain) * Transport type (TCP, UDP) * Optional authentication (username/password) * Custom headers for routing * Connection testing before deployment ## Phone Number Components ### Basic Information Each phone number includes: * **Phone Number**: The actual phone number in E.164 format * **Label**: Descriptive name for easy identification * **Provider Type**: The telephony provider (Twilio, SIP) * **Provider Credentials**: Provider-specific configuration ### Voice Agent Assignment **Assignment Options:** * **Assigned**: Phone number is assigned to a specific Voice Agent * **Unassigned**: Phone number is available but not assigned * **None**: Default state for new phone numbers **Assignment Rules:** * One phone number can be assigned to one agent at a time * Reassignment requires confirmation if number is in use * Unassigning makes the number available for other agents ### Provider Configuration **Twilio Configuration:** * Account SID (required) * Auth Token (required) * Automatic webhook configuration **SIP Trunk Configuration:** *Inbound Settings:* * Origination URI type (SIP-TCP, SIP-UDP) * Webhook URL (automatically configured by Hamsa) *Outbound Settings:* * Destination address (IP address or domain) * Transport type (TCP, UDP) * SIP trunk authentication (optional) * Username * Password * Custom headers (optional) * Key-value pairs for routing * Multiple headers supported **SIP Connection Testing:** * Test connectivity before saving * Validates destination reachability * Checks authentication if configured * Provides detailed error messages * Ensures proper configuration ### Webhook Configuration Phone numbers automatically receive webhook URLs for call events: * Inbound call initiation * Call status updates * Call completion events * Error notifications Webhooks are automatically configured by the platform based on your provider type. ## Phone Number Actions Available actions for phone numbers: | Action | Description | Availability | | ----------------------- | -------------------------------------------- | --------------------------------------- | | **Add Number** | Add a new phone number from a provider | Always | | **Assign Agent** | Assign a Voice Agent to handle inbound calls | When unassigned | | **Reassign Agent** | Change the assigned Voice Agent | When assigned | | **Unassign Agent** | Remove agent assignment | When assigned | | **Make Call** | Place an outbound test call | When assigned to an agent | | **View SIP Config** | View SIP trunk configuration details | SIP numbers only | | **Test SIP Connection** | Test SIP connectivity | SIP numbers only (during initial setup) | | **Delete** | Remove phone number from the system | Always | Reassignment and deletion actions require confirmation to prevent accidental changes. ## Prerequisites Before adding phone numbers, ensure you have: **Provider Account** * Active account with your chosen provider (Twilio or SIP trunk) * Valid credentials (API keys, tokens, or SIP address) * Phone number purchased from your provider (or SIP trunk configured) **Project Setup** * Active project selected * Appropriate permissions to manage phone numbers **Voice Agent Not Required**: You can add phone numbers without having a Voice Agent. Voice Agents are only needed when you want to assign numbers for inbound calls or make outbound calls. ## Common Use Cases ### Inbound Customer Support **Scenario**: Receive customer calls and route to support agent **Setup**: * Add phone number from Twilio * Assign to your customer support Voice Agent * Configure agent with knowledge base and tools * Test with incoming calls **Result**: Customers can call your number and speak with AI support agent ### Outbound Appointment Reminders **Scenario**: Make outbound calls for appointment reminders **Setup**: * Add phone number from your provider * Assign to appointment reminder Voice Agent * Configure agent with appointment details * Use "Make Outbound Call" feature to test **Result**: System can place calls to remind customers of appointments ### Enterprise SIP Integration **Scenario**: Integrate with existing enterprise SIP infrastructure **Setup**: * Configure SIP trunk with your carrier details * Set up inbound origination URI (SIP-TCP/UDP) * Configure outbound destination address * Add authentication credentials if required * Add custom headers for routing * Test SIP connection before deployment **Result**: Seamless integration with existing PBX and telephony infrastructure ### Multi-Agent Phone System **Scenario**: Multiple agents handling different phone lines **Setup**: * Add multiple phone numbers * Create specialized Voice Agents (sales, support, billing) * Assign each number to appropriate agent * Monitor calls in call history **Result**: Professional multi-line phone system with specialized AI agents ## SIP Trunk Best Practices ### Inbound Configuration 1. **Choose Right Protocol**: Select TCP for most deployments, UDP for lower latency 2. **Whitelist IPs**: Configure your firewall to allow Hamsa's IP addresses 3. **Test Connectivity**: Always test before going live 4. **Monitor Calls**: Check call history regularly for connection issues ### Outbound Configuration 1. **Validate Address**: Ensure SIP destination is reachable 2. **Test Authentication**: Verify username/password before deployment 3. **Use Custom Headers**: Add routing headers as required by your carrier 4. **Choose Transport**: TCP for reliability, UDP for lower latency 5. **Document Settings**: Keep records of your SIP configuration ### Security 1. **Secure Credentials**: Store SIP credentials securely 2. **Choose Appropriate Transport**: Use TCP for reliability, UDP for lower latency 3. **IP Whitelisting**: Restrict access to known IP ranges 4. **Regular Audits**: Review SIP access logs periodically 5. **Rotate Credentials**: Change SIP passwords regularly ## Phone Number Limitations ### Provider-Specific Limitations **Twilio:** * Requires valid Twilio account * Subject to Twilio's rate limits and pricing * Geographic availability varies **SIP Trunk:** * Requires proper network configuration * Firewall rules may need adjustment * Carrier-specific requirements vary * Custom headers depend on carrier support ### Platform Limitations **Assignment:** * One phone number can be assigned to one agent at a time * Reassignment requires existing calls to complete **Outbound Calls:** * Requires agent to be assigned * Requires valid API key configured * Subject to concurrency limits of your plan ## Getting Started 1. **Choose Provider** - Select Twilio or SIP Trunk based on your needs 2. **Gather Credentials** - Collect necessary credentials from your provider 3. **[Add Phone Number](./managing-numbers#adding-phone-numbers)** - Use the Phone Numbers section to add your number 4. **[Assign to Agent](./managing-numbers#assigning-phone-numbers-to-voice-agents)** (Optional) - Connect the number to a Voice Agent when ready 5. **Test Connection** - Make a test call to verify configuration 6. **Monitor Calls** - Track calls in [Call History](/agents/call-history/introduction) 7. **[Create Batch Calls](/agents/batch-calls/introduction)** (Optional) - Use your phone number for batch calls ## What's Next? * **[Quick Start](./quick-start)** - Get started with phone numbers in 4 simple steps * **[Managing Phone Numbers](./managing-numbers)** - Learn how to add, configure, and delete phone numbers * **[Making Outbound Calls](./making-calls)** - Understand how to place outbound calls * **[Best Practices](./best-practices)** - Optimize your phone number management ## Related Documentation Learn about creating and configuring Voice Agents Track and monitor all your calls Use your phone numbers for batch calls Learn how to use phone numbers in batch calls Monitor system performance # Making Outbound Calls Source: https://docs.tryhamsa.com/agents/phone-numbers/making-calls Learn how to make outbound calls using your phone numbers and Voice Agents ## Overview The outbound calling feature allows you to place test calls directly from the Hamsa dashboard using your configured phone numbers and Voice Agents. This is ideal for testing agent behavior, validating configurations, and demonstrating agent capabilities. **Outbound calls enable you to:** * Test Voice Agents before production deployment * Validate phone number configurations * Demonstrate agent capabilities to stakeholders * Pass custom parameters for personalized conversations * Configure webhooks for call event notifications **Individual Calls vs Batch Calls:** * **Individual Calls** (this page): Make single test calls from the dashboard - perfect for testing and demonstrations * **[Batch Calls](/agents/batch-calls/introduction)**: Execute batch calls to multiple recipients - ideal for production use * Both use the same phone numbers, but serve different purposes ## Prerequisites Before making outbound calls, ensure: **Phone Number Configuration:** * Phone number is added to the system * Number is assigned to a Voice Agent * Provider credentials are valid (Twilio or SIP) **Voice Agent:** * Agent exists and is properly configured * Agent is assigned to the phone number * Agent has been tested in browser **Project Configuration:** * Active project is selected * API key is configured in project settings * Sufficient concurrency available in your plan **Other:** * Valid destination phone number * Network connectivity **Supported Providers:** * Both Twilio and SIP trunk support outbound calls * Ensure your provider account has sufficient balance or connectivity ## Making a Basic Outbound Call ### Step 1: Access Outbound Call Feature 1. **Navigate to Phone Numbers** * Go to Dashboard → Phone Numbers * View list of configured phone numbers 2. **Select Phone Number** * Click on the phone number you want to use * Ensure it's assigned to a Voice Agent * Details panel opens 3. **Click Make Outbound Call** * In the details header, click "Make Outbound Call" button * Button is enabled only when: * Phone number is assigned to an agent * Agent exists in the system * API key is configured * Provider supports outbound calls ### Step 2: Configure Call Details **Destination Phone Number:** * Enter in E.164 format (e.g., +12025551234) * Must include country code * Must start with '+' * No spaces or special characters **Validation:** * System validates format * Invalid numbers show error message * Must be a valid phone number ### Step 3: Initiate Call 1. **Review Settings** * Verify destination number * Check source number * Confirm assigned agent 2. **Click "Make Call"** * Call is initiated immediately * Modal closes automatically * System displays success notification 3. **Answer Call** * Answer the phone at the destination number * Voice Agent begins conversation * Interact with agent as needed ### Step 4: Monitor Call 1. **View in Call History** * Navigate to Call History * Find your call in the list * Shows status: IN\_PROGRESS → COMPLETED 2. **Review Call Details** * Click the call to see details * View conversation transcript * Check call logs * Review outcomes ## Advanced Outbound Call Options ### Custom Parameters Pass dynamic variables to personalize the agent's conversation. **Use Cases:** * Customer name for personalized greeting * Order number for order status calls * Appointment details for reminders * Account information for verification **How to Add:** 1. In the outbound call modal 2. Scroll to "Custom Parameters" section 3. Click "Add Parameter" 4. Enter key and value: * Key: Variable name (e.g., 'customer\_name') * Value: Variable value (e.g., 'John Smith') 5. Add multiple parameters as needed 6. Remove parameters by clicking delete icon **Example:** | Key | Value | | ----------------- | ---------- | | customer\_name | John Smith | | order\_number | ORD-12345 | | appointment\_date | 2026-01-25 | | appointment\_time | 2:00 PM | **In Voice Agent Prompt:** ``` You are a helpful assistant. You are calling {customer_name} about order {order_number}. The appointment is scheduled for {appointment_date} at {appointment_time}. ``` **Parameter Requirements:** * Keys must be referenced in the Voice Agent's prompt or flow * Unused parameters are ignored (no error) * Values can be strings, numbers, or basic types * No validation on parameter format ### Webhook Configuration Configure webhooks to receive real-time call event notifications. **Supported Events:** * Call initiated * Call answered * Call in progress * Call completed * Call failed **How to Configure:** 1. **Enable Webhooks** * In outbound call modal * Toggle "Enable Webhook" switch 2. **Enter Webhook URL** * Must be HTTPS URL * Must be publicly accessible * Must return 200 status for delivery * Example: `https://api.example.com/call-events` 3. **Configure Authentication (Optional)** * **API Key**: Simple key-based authentication * Add header: `X-API-Key: your-api-key` * **Bearer Token**: JWT or OAuth token * Add header: `Authorization: Bearer your-token` * **Basic Auth**: Username and password * Add header: `Authorization: Basic base64(user:pass)` 4. **Test Webhook** * Use webhook testing tools * Verify your endpoint receives events * Check event payload structure **Webhook Payload Example:** ```json theme={null} { "event": "call.completed", "call_id": "call_abc123xyz", "timestamp": "2026-01-22T10:30:00Z", "from_number": "+12025551234", "to_number": "+12025555678", "duration": 125, "status": "COMPLETED", "cost": 0.015, "conversation": { "transcript": "...", "summary": "..." } } ``` **Webhook Security:** * Always use HTTPS endpoints * Implement authentication * Validate webhook signatures if available * Rate limit your webhook endpoint * Log webhook events for debugging ## Use Cases ### Testing Voice Agent Configuration **Scenario**: Verify agent behavior before production **Steps:** 1. Configure Voice Agent with desired prompts and tools 2. Assign agent to test phone number 3. Make outbound call to your own phone 4. Interact with agent to test: * Greeting and introduction * Question answering * Tool executions * Call flow logic * Error handling 5. Review call in Call History 6. Iterate on agent configuration as needed **Benefits:** * Low-risk testing environment * Immediate feedback * No impact on production calls * Easy iteration ### Demonstrating Agent Capabilities **Scenario**: Show stakeholders what the agent can do **Steps:** 1. Prepare demonstration script 2. Configure agent with relevant knowledge base 3. Set up outbound call to stakeholder's phone 4. Add custom parameters for personalized demo 5. Place call during presentation 6. Show live interaction 7. Review Call History together **Benefits:** * Live demonstration * Real phone experience * Builds confidence * Immediate feedback ### Appointment Reminders **Scenario**: Automated appointment reminder calls **Steps:** 1. Create appointment reminder Voice Agent 2. Assign to outbound phone number 3. Prepare appointment details as parameters 4. Make call with parameters: * patient\_name: 'Jane Doe' * appointment\_date: '2026-01-25' * appointment\_time: '2:00 PM' * doctor\_name: 'Dr. Smith' 5. Agent delivers personalized reminder 6. Configure webhook to track confirmations **Benefits:** * Automated reminders * Personalized experience * Reduced no-shows * Cost-effective ### Order Status Updates **Scenario**: Proactive customer communication **Steps:** 1. Create order update Voice Agent 2. Configure with order tracking knowledge 3. Make call with order parameters: * customer\_name: 'John Smith' * order\_number: 'ORD-12345' * tracking\_number: 'TRACK-789' * delivery\_date: '2026-01-24' 4. Agent provides order status 5. Webhook captures customer response **Benefits:** * Proactive communication * Improved customer satisfaction * Reduced support inquiries * Scalable solution ## Limitations and Considerations ### Call Limitations **Provider Limits:** * Subject to provider's rate limits * Geographic restrictions may apply * Cost per call varies by destination * Some countries may be blocked **Platform Limits:** * Concurrent calls limited by your plan * API key required for all calls * Outbound call history tracked * Cost deducted from your account **Provider-Specific:** **Twilio:** * Uses Twilio account balance * Subject to Twilio's compliance rules * May require caller ID verification * Some regions require local numbers **SIP Trunk:** * Depends on trunk configuration * May require carrier approval * Custom routing rules apply * Authentication must be configured ## Troubleshooting ### Cannot Make Outbound Call **Button Disabled:** Check if: * Phone number is assigned to a Voice Agent * Voice Agent exists and is not deleted * API key is configured in project settings * You have sufficient permissions **Solutions:** * Assign Voice Agent if unassigned * Verify agent exists in Voice Agents section * Configure API key in project settings * Check provider type * Contact administrator for permissions ### Call Fails to Connect **Possible Causes:** * Invalid destination number format * Destination number blocked by provider * Insufficient balance (Twilio) * Network connectivity issues * SIP trunk misconfiguration **Solutions:** * Verify E.164 format (+country code) * Check provider account status * Ensure sufficient balance * Test with known working number * Review SIP trunk configuration * Check Call History for error details ### Agent Not Responding **Possible Causes:** * Voice Agent configuration issues * LLM API errors * Knowledge base not processing * Tool integration failures **Solutions:** * Test agent in browser first * Check agent configuration * Verify LLM API key is valid * Review knowledge base status * Check tool configurations * Review call logs in Call History ### Webhook Not Receiving Events **Possible Causes:** * Invalid webhook URL * URL not publicly accessible * Firewall blocking requests * Authentication failing * Endpoint returning errors **Solutions:** * Verify URL is correct and HTTPS * Test with webhook testing tools * Check firewall rules * Verify authentication credentials * Monitor endpoint logs * Return 200 status code ## Related Documentation Overview of Phone Numbers features Add and configure phone numbers Use your phone numbers for batch calls Learn how to use phone numbers in batch calls Track and monitor all calls # Managing Phone Numbers Source: https://docs.tryhamsa.com/agents/phone-numbers/managing-numbers Comprehensive guide to adding, configuring, assigning, and deleting phone numbers ## Overview Learn how to effectively manage your phone numbers in the Hamsa platform. This guide covers adding numbers from different providers, configuring them, assigning them to Voice Agents, and managing their lifecycle. ## Adding Phone Numbers ### Adding a Twilio Number 1. **Navigate to Phone Numbers** * Go to Dashboard → Phone Numbers * Click the "Add Phone Number" button * Select "Twilio" from the provider dropdown 2. **Enter Phone Number Details** * **Phone Number**: Enter in E.164 format (e.g., +12025551234) * Must start with '+' * Include country code * No spaces or special characters * **Label**: Enter a descriptive name (1-100 characters) * Examples: 'Main Support', 'Sales Line', 'Emergency Hotline' * Helps identify the number's purpose 3. **Enter Twilio Credentials** * **Twilio Account SID**: Found in your Twilio Console * **Twilio Auth Token**: Found in your Twilio Console * These credentials allow Hamsa to configure webhooks automatically 4. **Save Configuration** * Click "Save" to create the phone number * System validates credentials and configures webhooks * Number appears in the list upon successful creation **Twilio Webhook Configuration:** When you add a Twilio number, Hamsa automatically configures the necessary webhooks in your Twilio account. This ensures inbound calls are routed correctly to your Voice Agents. ### Adding a SIP Trunk 1. **Navigate to Phone Numbers** * Go to Dashboard → Phone Numbers * Click the "Add Phone Number" button * Select "SIP Trunk" from the provider dropdown 2. **Enter Basic Information** * **Label**: Enter a descriptive name for the trunk * **Phone Number**: Choose one of two options: * **Phone Number** (radio button): * Select country code from the dropdown (e.g., US +1) * Enter phone number in the input field * Use this for standard phone number format * **Other** (radio button): * Enter phone number or identifier in custom format * Use this for non-standard formats or custom identifiers * Enter directly in the text input field 3. **Configure Inbound Settings** **Origination URI:** * Select the protocol type: * **SIP-TCP**: Standard TCP connection (most common) * **SIP-UDP**: UDP connection (lower latency) **Webhook URL:** * Automatically provided by Hamsa * Copy this URL to your SIP trunk configuration * Used for inbound call handling 4. **Configure Outbound Settings** **Address (Required):** * Enter your SIP destination * Can be an IP address (e.g., 192.168.1.100) or domain (e.g., sip.example.com) * Must be reachable from Hamsa's infrastructure **Transport Type (Required):** * **TCP**: Reliable, connection-oriented (recommended) * **UDP**: Connectionless, lower overhead **Authentication (Optional):** * **SIP Trunk Username**: If your trunk requires authentication * **SIP Trunk Password**: Corresponding password * Leave empty if your trunk uses IP-based authentication **Custom Headers (Optional):** * Add key-value pairs for call routing, metadata, or carrier integration * Click the "+ Add Header" button to add a new header * Enter a key in the left field (e.g., 'X-Carrier-ID', 'X-Trunk-Group') * Enter a value in the right field (e.g., 'CARRIER123', 'PRIMARY') * Add multiple headers as needed * Remove headers by clicking the trash icon on the right * Examples: * Key: 'X-Carrier-ID', Value: 'CARRIER123' * Key: 'X-Trunk-Group', Value: 'PRIMARY' * Key: 'X-Route-ID', Value: 'ROUTE456' 5. **Test Connection** * Click "Test Connection" button * System validates: * Destination reachability * Authentication credentials (if provided) * Network connectivity * Review test results: * ✅ Success: Configuration is correct * ❌ Failed: Review error message and fix issues 6. **Save Configuration** * Click "Save" after successful connection test * Number becomes available for assignment **SIP Trunk Requirements:** * Your SIP trunk must be configured to accept connections from Hamsa * Firewall rules may need to allow Hamsa's IP addresses * Coordinate with your telephony provider for proper setup * Test thoroughly before production use ### Provider-Specific Considerations **Twilio:** * Requires active Twilio account with available balance * Phone number must be purchased in Twilio first * Supports SMS and voice capabilities * Geographic restrictions may apply * Subject to Twilio's pricing and rate limits **SIP Trunk:** * Requires coordination with your telephony provider * May need firewall configuration changes * Supports advanced routing scenarios * Custom header support varies by carrier * IP whitelisting may be required ## Viewing Phone Number Details 1. **Access Phone Number List** * Navigate to Phone Numbers section * View all configured phone numbers * Numbers display with: * Provider icon (Twilio or SIP) * Label * Phone number 2. **Select a Phone Number** * Click any phone number in the list * Details panel opens on the right (desktop) * Full-screen details on mobile 3. **Review Information** **Basic Information Card:** * Phone number with copy button * Label * Provider type badge * Creation timestamp **Voice Agent Assignment Card:** * Current assignment status * Dropdown to change assignment * Reassignment confirmation when needed **Provider Configuration Card:** *For Twilio:* * Twilio Account SID * Webhook URL (automatically configured) *For SIP Trunk:* * View SIP configuration button * Opens modal with full SIP details * Includes inbound and outbound settings ## Assigning Phone Numbers to Voice Agents ### Initial Assignment 1. **Select Unassigned Number** * Choose a phone number with "None" assignment * Open the phone number details 2. **Choose Voice Agent** * In "Voice Agent Assignment" card * Click the dropdown (showing "None") * Select desired Voice Agent from list * Assignment happens immediately 3. **Verify Assignment** * Dropdown now shows selected agent * Number ready to receive calls * Inbound calls route to assigned agent ### Reassigning a Phone Number 1. **Select Assigned Number** * Choose phone number currently assigned to an agent * Open phone number details 2. **Change Assignment** * Click the Voice Agent dropdown * Select a different agent * Reassignment dialog appears 3. **Confirm Reassignment** * Dialog warns about changing assignment * Lists current and new agent * Click "Confirm" to proceed * Click "Cancel" to abort 4. **Assignment Updated** * New agent now handles inbound calls * Old agent no longer receives calls on this number * Change is immediate **Reassignment Impact:** * Active calls are not interrupted * New inbound calls route to new agent immediately * Ensure new agent is properly configured * Test after reassignment to verify ### Unassigning a Phone Number 1. **Select Assigned Number** * Choose phone number with agent assigned * Open phone number details 2. **Remove Assignment** * Click Voice Agent dropdown * Select "None" from the list * Confirmation may be required 3. **Number Unassigned** * Number no longer receives calls * Can be reassigned to different agent * Useful for maintenance or reconfiguration ## Managing SIP Trunk Configuration ### Viewing SIP Configuration 1. **Open SIP Number Details** * Select a SIP trunk number from the list * Details panel displays 2. **View Configuration** * In Provider Configuration card * Click "View SIP Configuration" button * Modal opens with full details 3. **Configuration Details** **Inbound Configuration:** * Origination URI (protocol type) * Webhook URL to configure in your trunk **Outbound Configuration:** * Destination address * Transport type * Authentication status (if configured) * Custom headers (if configured) 4. **Copy Information** * Use copy buttons for URLs and addresses * Share with telephony provider as needed * Keep records for troubleshooting ### Testing SIP Connection The "Test Connection" function is only available during the initial setup when adding a new SIP trunk. It cannot be accessed from existing phone number details. 1. **Access Test Function** * Available only when adding a new SIP trunk * Click "Test Connection" button in the outbound configuration section * Must be done before saving the phone number 2. **Test Execution** * System attempts connection to SIP destination * Validates authentication if configured * Checks network reachability * Process takes 5-10 seconds 3. **Review Results** **Success:** * Green success message * Connection parameters validated * Safe to save and use for production calls **Failure:** * Red error message with details * Common issues: * Destination unreachable * Authentication failed * Firewall blocking connection * Invalid address format * Fix issues and retest before saving **Important:** * Test Connection is only available during initial SIP trunk setup * You must test before saving the phone number * If you need to test an existing SIP trunk, you'll need to check call history or make a test call * Always test during setup to ensure proper configuration before deployment ## Deleting Phone Numbers ### Delete Process 1. **Select Phone Number** * Choose number to delete * Open details panel 2. **Initiate Deletion** * Click "Delete" button in header * Located next to "Make Outbound Call" button 3. **Confirm Deletion** * Confirmation dialog appears * Shows phone number and label * Warns that action cannot be undone * Click "Delete" to confirm * Click "Cancel" to abort 4. **Number Removed** * Phone number deleted from system * No longer appears in list * Cannot receive or place calls * Assignment removed if was assigned **Deletion is Permanent:** * Cannot be undone * All configuration is lost * Must re-add if needed later * Active calls may be interrupted * Ensure number is not critical before deleting ### Pre-Deletion Checklist Before deleting a phone number: * [ ] Verify number is not actively receiving important calls * [ ] Check if number is published in marketing materials * [ ] Confirm replacement number is configured (if applicable) * [ ] Notify team members of the change * [ ] Update any documentation referencing the number * [ ] Consider unassigning instead of deleting for temporary changes ## Troubleshooting ### Phone Number Not Saving **Possible Causes:** * Invalid phone number format * Missing required fields (credentials, address) * Network connectivity issues * Invalid Twilio credentials * SIP destination unreachable **Solutions:** * Verify phone number is in E.164 format * Check all required fields are filled * Validate credentials with provider * Test SIP connection before saving * Check browser console for errors ### Assignment Changes Not Working **Possible Causes:** * Voice Agent was deleted * Network issues during save * Insufficient permissions * Browser cache issues **Solutions:** * Verify agent exists in Voice Agents section * Refresh the page and try again * Check permissions with administrator * Clear browser cache * Try different browser ### SIP Connection Test Fails **Common Issues:** **Destination Unreachable:** * Verify address is correct (IP or domain) * Check network connectivity * Confirm firewall allows outbound SIP * Verify DNS resolution for domains **Authentication Failed:** * Verify username and password * Check for typos in credentials * Confirm credentials with provider * Test with IP authentication if available **Timeout:** * Destination may be down * Network latency too high * Firewall blocking connection * Try different transport type ### Calls Not Routing Correctly **For Twilio:** * Verify Twilio webhook is configured * Check Twilio account is active * Ensure sufficient balance * Review Twilio debugger logs **For SIP:** * Verify SIP configuration is correct (test during initial setup) * Verify inbound webhook configuration * Check firewall allows inbound SIP * Review custom headers with provider * Check Call History for connection issues ## Using Phone Numbers for Batch Calls Phone numbers can be used as the "From Number" in [Batch Calls](/agents/batch-calls/introduction) to execute batch calls. ### Requirements **For Batch Calls:** * Phone number must be configured and available in your account * Number must support outbound calling (Twilio or SIP Trunk) * Phone number does not need to be assigned to a Voice Agent (the batch call uses its own Voice Agent) * Number must exist before creating the batch call ### How It Works 1. **Add Phone Number** - [Create your phone number](#adding-phone-numbers) using Twilio or SIP Trunk 2. **Create Batch Call** - Go to [Batch Calls](/agents/batch-calls/introduction) section 3. **Select From Number** - Choose your phone number from the "From Number" dropdown 4. **Select Voice Agent** - Choose the Voice Agent that will handle the batch calls 5. **Upload Recipients** - Upload CSV with recipient phone numbers 6. **Configure Schedule** - Set when calls should run 7. **Execute** - Batch calls use your phone number to call all recipients **Batch Calls vs Individual Calls:** * **Individual Calls**: Use the [Make Outbound Call](./making-calls) feature for single test calls * **Batch Calls**: Use [Batch Calls](/agents/batch-calls/introduction) for bulk campaigns with multiple recipients * Both use the same phone numbers, but batch calls are more efficient for large-scale operations ### Batch Call Benefits **Efficiency:** * Execute hundreds or thousands of calls automatically * Better concurrency management * Automated scheduling and time constraints * Individual recipient status tracking **Management:** * Pause, resume, or cancel entire campaigns * Retry failed or unanswered calls * Track progress in real-time * Export recipient data **Use Cases:** * Appointment reminders * Marketing campaigns * Customer notifications * Survey calls * Emergency alerts Learn more about creating and managing batch calls in the [Batch Calls documentation](/agents/batch-calls/introduction). ## Related Documentation Overview of Phone Numbers features Get started quickly with phone numbers Learn how to place individual outbound calls Use phone numbers for batch calls Step-by-step guide to creating batch calls Optimize your phone number usage # Quick Start Source: https://docs.tryhamsa.com/agents/phone-numbers/quick-start Get started with Phone Numbers in 4 simple steps ## Overview Get up and running with Phone Numbers quickly. Follow these steps to add a phone number, assign it to a Voice Agent, and start making calls. ## Prerequisites Before getting started, ensure you have: * An active project selected * Appropriate permissions to manage phone numbers * Provider credentials (Twilio Account SID and Auth Token, or SIP trunk details) * A phone number from your provider (Twilio) or SIP trunk configured **Voice Agent Optional**: You don't need a Voice Agent to add phone numbers. Voice Agents are only required when assigning numbers for inbound calls or making outbound calls. ## Quick Start Steps ### 1. Navigate to Phone Numbers * Go to the [Phone Numbers section](https://agents.tryhamsa.com/app/provider-numbers) in your dashboard * Or navigate via Dashboard → Bring Your Own Phone Number Navigate to Phone Numbers section Navigate to Phone Numbers section ### 2. Add a Phone Number #### For Twilio: * Click the "Add Number" button * Select "Twilio" from the dropdown Phone Numbers section with Add Number button Phone Numbers section with Add Number button * Fill in the required information: * **Phone Number**: Enter your Twilio phone number in E.164 format (e.g., +12025551234) * **Label**: Provide a descriptive name (e.g., 'Support Line', 'Sales Hotline') * **Twilio Account SID**: Enter your Twilio Account SID * **Twilio Auth Token**: Enter your Twilio Auth Token * Click "Save" to add the phone number Phone Numbers section with Add Twilio Number details Phone Numbers section with Add Twilio Number #### For SIP Trunk: * Click the "Add Number" button * Select "SIP Trunk" from the dropdown Phone Numbers section with Add SIP Number Phone Numbers section with Add SIP Trunk Number details * Fill in the required information: * **Label**: Provide a descriptive name * **Phone Number**: Choose one of two options: * **Phone Number** (radio button): Select country code from dropdown and enter phone number in standard format * **Other** (radio button): Enter phone number or identifier in custom format (text input field) New Phone Number form with Number Config, Inbound and Outbound Configuration New Phone Number form with Number Config, Inbound and Outbound Configuration * Configure **Inbound Settings**: * Select Origination URI type (SIP-TCP or SIP-UDP) * Copy the provided webhook URL to configure in your SIP trunk * Configure **Outbound Settings**: * **Address**: Enter SIP destination (IP or domain) * **Transport Type**: Select TCP or UDP * **Authentication** (optional): * SIP Trunk Username * SIP Trunk Password * **Custom Headers** (optional): * Click the "+ Add Header" button to add a new header * Enter a key (e.g., 'X-Carrier-ID', 'X-Trunk-Group') * Enter a value (e.g., 'CARRIER123', 'PRIMARY') * Add multiple headers as needed for routing, metadata, or carrier integration * Remove headers by clicking the trash icon * Custom headers are used for call routing and carrier-specific requirements Custom SIP Headers section with Add Header button and key/value inputs Custom SIP Headers section with Add Header button and key/value inputs * Click "Test Connection" to verify your SIP configuration Test Connection section for SIP configuration Test Connection section for SIP configuration * Click "Save" when the connection test passes **Finding Twilio Credentials:** * Log in to your [Twilio Console](https://console.twilio.com/) * Find your Account SID and Auth Token on the dashboard * Ensure you have purchased a phone number in Twilio **SIP Trunk Setup:** * Obtain SIP trunk details from your telephony provider * Configure your SIP trunk to accept connections from Hamsa * Add the provided webhook URL to your trunk configuration * Whitelist Hamsa's IP addresses in your firewall if needed ### 3. Assign to Voice Agent * After saving, your phone number appears in the list * Click the phone number to view details * In the "Voice Agent Assignment" section: * Click the dropdown showing "None" * Select a Voice Agent from the list * Confirm the assignment If reassigning an already assigned number, you'll be asked to confirm the change to prevent accidental reassignment. ### 4. Test Your Setup #### For Inbound Calls: * Call your phone number from any phone * Your assigned Voice Agent should answer * Have a conversation to test the agent's responses * Check Call History to review the call details #### For Outbound Calls: * Click "Make Outbound Call" in the phone number details * Enter the destination phone number * Add any custom parameters (optional) * Configure webhook URL and authentication (optional) * Click "Make Call" * Answer the call on the destination phone * Check Call History for call details **Outbound Call Requirements:** * Phone number must be assigned to a Voice Agent * API key must be configured in your project settings * The assigned Voice Agent must exist and be properly configured ## Next Steps Now that you've added and configured your first phone number: * **[Managing Phone Numbers](./managing-numbers)** - Learn detailed steps for managing your phone numbers * **[Making Outbound Calls](./making-calls)** - Understand all outbound calling options * **[Batch Calls](/agents/batch-calls/introduction)** - Use your phone number for batch calls * **[Best Practices](./best-practices)** - Optimize your phone number usage ## Common Issues ### Phone Number Not Receiving Calls **Twilio:** * Verify your Twilio credentials are correct * Check that the phone number is active in Twilio * Ensure Twilio webhook is properly configured * Verify your Twilio account has sufficient balance **SIP Trunk:** * Verify SIP destination address is reachable * Check firewall rules allow SIP traffic * Ensure custom headers are correct for your carrier * Test SIP connection during initial setup (before saving) * Verify authentication credentials if used ### Cannot Make Outbound Calls **Troubleshooting:** * Ensure phone number is assigned to a Voice Agent * Verify the assigned agent exists and is configured * Check that your API key is configured in project settings * Verify you have available concurrency in your plan * For SIP: ensure outbound configuration is correct ### Assignment Fails **Possible causes:** * Voice Agent may have been deleted * Insufficient permissions to assign numbers * Network connectivity issues **Solutions:** * Refresh the page and try again * Verify the agent exists in the Voice Agents section * Check your permissions with your administrator * Contact support if issue persists ## Related Documentation Learn more about Phone Numbers features and capabilities Detailed guide on phone number management How to make outbound calls using your phone numbers Create and configure Voice Agents Use phone numbers for batch calls # Embed on your website Source: https://docs.tryhamsa.com/agents/publishing/embed Add your published agent to your own website as a floating widget. Once your agent is [published](/agents/publishing/publish-agent), you can embed it on your own website. The embed adds a floating button to your pages; when a visitor clicks it, the agent opens in a full-screen overlay — the same public page, framed inside your site. Publish your agent first. The embed uses your agent's publish token, so the agent must be published for the widget to work. If you unpublish, the widget stops working. ## Add the widget 1. On the agent's publish page, open the **Embed** section. 2. Copy the ` ``` Always copy the snippet from your dashboard — it has the correct token and your configured appearance. The attributes below are for reference. ## Configuration Add `data-*` attributes to the ` ``` You can add `data-hamsa-trigger` to as many elements as you like, including ones added after the page loads. ## How it works * The script adds a floating button to your page. * Clicking the button (or any `data-hamsa-trigger` element) opens the agent in a full-screen overlay on top of your site. * The visitor talks to the agent just like on the public page. * Closing the overlay (the close button or the **Esc** key) returns them to your site. ## Related Create the public page the widget loads. # Publish agent Source: https://docs.tryhamsa.com/agents/publishing/publish-agent Turn any agent into a public page that anyone can open in a browser and talk to — no sign-in required. Publishing gives your agent a public page on the web. Anyone you send the link to can open it in a browser and talk to the agent by voice — no account or sign-in needed. It's the fastest way to let people use your agent, or to test it yourself. ## Publish your agent 1. Open the agent you want to publish. 2. Click **Publish** in the agent's header. The publish page opens, with appearance settings on the left and a live preview on the right. 3. Adjust the appearance if you want (see [Appearance](#appearance)). The preview updates as you change settings and uses no call credits. 4. Click **Publish agent**. The page switches to show your public link. ## Your public link Once published, your agent is available at: ```text theme={null} https://agents.tryhamsa.com/publish/ ``` Use **Copy** to grab the link, or open it in a new tab to try it. Anyone with the link can start a voice conversation with the agent — no sign-in required. The page asks the visitor for microphone permission, then connects them to the agent. Visitors never see your dashboard or account. ## Appearance Customize how the public page looks. Every change shows in the live preview before you publish. * **Theme** — Light or dark default for the page. * **Visitor theme switcher** — Show a light/dark toggle so each visitor can pick their own; their choice is remembered on their device. * **Visualizer** — The animated audio visual (orb, wave, bar, radial, grid, or aura) and its colors. * **Accent color** — The color of the call button (set for light and dark). * **Page background** — A background color (light and dark), or a background image. * **Logo** — A logo shown in the top-left corner. * **Agent name** — Show or hide the agent's name on the page. * **Description** — A short line under the agent name. * **Call to action** — A short line shown before the call starts. ## Test your agent To try the published agent yourself, open the public link in a new tab and start a call — exactly as your users will. Share the link with others to have them test it too. ## Unpublish To take the agent offline, open the publish page and click **Unpublish**. Unpublishing takes effect immediately. The public link — and any [embedded widget](/agents/publishing/embed) that uses it — stops working right away and shows "Agent not available." If you publish again later, update the embed script on your website. ## Related Add the published agent to your own site as a floating widget. # Call Behavior Settings Source: https://docs.tryhamsa.com/agents/single-prompt/call-behavior Configure response timing, interruptions, inactivity handling, and call duration for your single prompt agent ## Overview Call behavior settings control the timing and flow of your agent's conversations. They are found in the **Call Settings** section of your agent's configuration. ## Response Delay How long the agent waits after detecting the user has stopped speaking before generating a response. **Range:** 100–1500ms **Default:** 400ms **Increment:** 100ms A shorter delay feels more responsive; a longer delay gives users more time to finish their thoughts without being interrupted. ## Interruption Handling Controls whether users can speak while the agent is talking, cutting off the agent's response. **Toggle:** Interrupt (on/off) **Default:** On When enabled, the agent stops speaking as soon as the user starts talking. When disabled, the agent completes its full response before listening again. ## User Inactivity Timeout How many seconds of silence trigger the agent to check if the user is still on the line. **Range:** 5–60 seconds **Default:** 15 seconds After the timeout, the agent proactively prompts the user. You can define what the agent says in your prompt. ## Max Call Duration The maximum length a call can run before being automatically terminated. **Range:** 30 seconds – 1 hour **Default:** 300 seconds (5 minutes) Most calls should end naturally via Smart Call End. Max Call Duration is a safety net for runaway calls. ## Ambient Sound Adds subtle ambient sound to the agent's audio. **Toggle:** Ambient Sound (on/off) **Default:** Off Do not enable both Background Noise and Noise Cancellation — they conflict and create audio artifacts. ## Thinking Voice Plays a thinking/processing sound between responses, making the agent feel more natural during pauses. **Toggle:** Thinking Voice (on/off) **Default:** Off ## Minimum Interruption Duration The minimum duration of speech required to register as an interruption. **Range:** 0.2–1.5 seconds **Default:** 0.5 seconds Increasing this reduces false interruptions from background noise or brief sounds. ## VAD Activation Threshold Voice activity detection sensitivity — how loud a sound needs to be before the system considers it speech. **Range:** 0.2–0.9 **Default:** 0.5 Higher values make the system less sensitive (ignores quieter sounds); lower values pick up more input. ## Wait for User to Speak First Controls whether the agent speaks first or waits for the caller to initiate. Options: * **Never** — Agent always speaks first * **Always** — Agent always waits * **Outbound calls only** — Agent waits only on outbound calls ## Next Steps Enable smart features like gender detection and smart call end Optimize your agent's instructions for better behavior Choose the right voice and language settings Test your agent before going live # Configure Settings Source: https://docs.tryhamsa.com/agents/single-prompt/configure-settings Overview of all configuration settings for single prompt agents This page is a quick reference for all settings available in the single prompt agent configuration panel. Each section links to a dedicated page with full details. ## Prompt Settings These settings appear below the system prompt editor: | Setting | Options | Default | | -------------------- | --------------------------- | ------- | | Enhanced Turn Taking | On / Off | Off | | Prompt Enhancer | Disabled / Basic / Advanced | Basic | **Enhanced Turn Taking** enables better numeral capturing and backchannel detection for more natural conversations. **Prompt Enhancer** applies automatic enhancements to your prompt. Basic adds stable model-agnostic improvements; Advanced adds model-aware prompts with live context. ## Voice Settings Select a voice from Hamsa's library, filtered by language, gender, dialect (Arabic only), and style. Language is set automatically when you choose a voice. | Setting | Range | Default | | ------------------ | -------------------------------- | ------------ | | Expressiveness | 0.0–2.0 | 1.0 | | Voice Dictionaries | Multi-select | None | | STT Model | Hamsa-STT-S2 / S3-beta / English | Hamsa-STT-S2 | → See [Voice Settings](./voice-settings) for full details. ## Call Behavior Settings | Setting | Range | Default | | ----------------------------- | ------------------------------ | ------- | | Wait for User to Speak First | Never / Always / Outbound only | Never | | User Gender Detection | On / Off | Off | | Smart Call End | On / Off | Off | | Language/Dialect Switcher | On / Off | Off | | Interrupt | On / Off | On | | Ambient Sound | On / Off | Off | | Thinking Voice | On / Off | Off | | Speaker Identification (Beta) | On / Off | Off | | Response Delay | 100–1500ms | 400ms | | User Inactivity Timeout | 5–60s | 15s | | Max Call Duration | 30s – 1 hour | 5 min | | Minimum Interruption Duration | 0.2–1.5s | 0.5s | | VAD Activation Threshold | 0.2–0.9 | 0.5 | → See [Call Behavior](./call-behavior) for full details. → See [Intelligence Features](./intelligence-features) for details on Gender Detection, Smart Call End, Speaker Identification, and Language/Dialect Switcher. ## LLM Settings | Setting | Options | Default | | ----------- | -------------------------------------- | --------------------- | | Provider | OpenAI, Gemini, Groq, DeepMyst, Custom | Gemini | | Model | Varies by provider | Gemini 3.1 Flash Lite | | Temperature | 0.0–1.0 | 0.2 | Temperature controls response variability. Lower values produce more consistent outputs; higher values produce more natural-sounding variation. GPT-5 family models (GPT-5, GPT-5-Mini, GPT-5-Nano) require temperature = 1.0. This is set automatically when you select a GPT-5 model. → See [LLM Configuration](/overview/features/llm-configuration) for the full model list. ## Noise Cancellation Removes background noise from the caller's audio. | Setting | Options | Default | | ----------------------- | -------------------------------------------------- | ---------------- | | Model | Disabled / Telephony Optimized / General Use Cases | Disabled | | Strategy (when enabled) | Per Conversation / Per Turn | Per Conversation | | Auto Gain Control | On / Off | Off | | Send Denoised to STT | On / Off | Off | **Ambient Sound** — Adds subtle ambient sound to the agent's audio. Do not combine with Noise Cancellation. **Thinking Voice** — Plays a thinking/processing sound between responses. ## Intelligence Features | Feature | Description | | ----------------------------- | -------------------------------------------------------------------------------- | | Gender Detection | Detects caller's likely gender for appropriate speech forms (helpful for Arabic) | | Smart Call End | Automatically ends the call when the conversation concludes naturally | | Speaker Identification (Beta) | Distinguishes multiple speakers on the same call | | Agentic RAG | Agent decides when to search the knowledge base for improved accuracy | | Language Dialect Switcher | Switches language or dialect instantly when the user requests | → See [Intelligence Features](./intelligence-features) for full details. ## Next Steps Enhance your agent with reference documents Connect custom functions and APIs Receive call events and data Test before going live # Intelligence Features Source: https://docs.tryhamsa.com/agents/single-prompt/intelligence-features Advanced AI capabilities including gender detection, smart call end, speaker identification, agentic RAG, and language dialect switcher ## Overview Intelligence features are optional AI capabilities you can enable per agent in the **Call Settings** section of your configuration. Each can be enabled or disabled independently. ## Gender Detection Detects the caller's likely gender and injects this context into the conversation, allowing the agent to use appropriate forms of speech. This is especially helpful for Arabic-speaking agents where gendered language forms are common. **To enable:** Call Settings → User Gender Detection toggle When enabled, you can instruct your agent how to use this information in your prompt: ```markdown theme={null} When greeting users, be respectful and use appropriate language. - If the caller is detected as male: Use "sir" as appropriate - If the caller is detected as female: Use "ma'am" as appropriate - If gender is unknown: Use gender-neutral language ``` ## Smart Call End Automatically detects when a conversation is complete and ends the call gracefully, without requiring the user to explicitly hang up. **To enable:** Call Settings → Smart Call End toggle The default prompt terminates the call when: (1) all customer inquiries have been resolved, (2) the conversation has reached a natural conclusion, (3) the customer's goal has been achieved, or (4) further conversation would be unproductive. When enabled, a text area appears below the toggle where you can customize the end-call prompt. A **Restore default** button resets the prompt to the built-in default. ## Speaker Identification Beta Distinguishes between different speakers on the same call and tracks who said what throughout the conversation. **To enable:** Call Settings → Speaker Identification toggle Useful for speakerphone calls, family or joint account calls, or any scenario where multiple people are on the line. Works best with clear audio and distinct voices. Do not use Speaker Identification for authentication or security purposes. ## Agentic RAG Enables the agent to decide when to search the knowledge base, rather than searching on every turn. Adds latency but improves accuracy for complex questions. **To enable:** Knowledge Base section → Agentic RAG toggle Requires at least one knowledge base item to be attached. ## Language Dialect Switcher Switches the agent's language or dialect instantly when the user requests a change. For example, an agent configured with Egyptian Arabic can switch to Gulf Arabic mid-conversation if the caller asks. **To enable:** Call Settings → Language/Dialect Switcher toggle This feature is designed for Arabic dialect variation. English operates with a single general speech recognition model. ## Next Steps Leverage intelligence features in your prompts Configure timing and interaction controls Set up a knowledge base for Agentic RAG Test your agent before going live # Single Prompt Agent Overview Source: https://docs.tryhamsa.com/agents/single-prompt/overview Simple, fast, and effective for straightforward conversational scenarios ## What is a Single Prompt Agent? A single prompt agent uses one comprehensive prompt (called a "preamble") to define all agent behaviors. This approach is the simplest and fastest way to create a voice agent, perfect for straightforward conversational scenarios. ## When to Use Single Prompt Agents Single prompt agents are ideal when: * Your conversation flow is relatively linear * You don't need complex conditional branching * Your prompt is under 500 words * You're using 3 or fewer custom tools/functions * You need to build and deploy quickly ## When to Upgrade to Flow Agent Consider upgrading to a Flow Agent when: * Your single prompt exceeds 500 words * You need complex decision trees with multiple paths * You require more than 3 custom tools * You need fine-grained control over different conversation stages * You want visual representation of your conversation flow * You need to reuse conversation components across agents ## Key Components ### 1. **Preamble (System Prompt)** The core instructions that define your agent's behavior, personality, task, and guidelines. This is where you tell the agent: * Who it is (identity) * How to behave (style and tone) * What to do (tasks and goals) * What not to do (guardrails and limitations) ### 2. **Greeting Message** The first thing your agent says when a call starts. Can be: * **Static**: A fixed greeting message * **Prompt-based**: Dynamically generated based on context ### 3. **Global Settings** Configuration applied to all conversations: * Voice and language selection * LLM model and parameters * Response timing and interruption handling * Call behavior settings ### 4. **Knowledge Base** (Optional) Upload documents, web content, or custom text that your agent can reference during conversations. ### 5. **Tools** (Optional) Extend your agent's capabilities with tools: * **API Request Tools** — server-side API calls (work on phone and web) * **MCP Tools** — Model Context Protocol integrations (server-side) * **Webhook Tools** — trigger external webhooks during conversation * **Web Tools** — client-side JavaScript functions that run in the browser (SDK deployments only). These can navigate the user, open modals, read page data, and more. See [Web Tools](/agents/tools/web-tools) for details. ### 6. **Variables & Parameters** (Optional) Define structured data that your agent should collect during calls, with optional outcome schema for structured responses. Single-prompt agents support **system variables** and **custom variables** (passed as `params`). See [Variable System](/agents/variables/introduction) for full reference. ## Setup Process Creating a single prompt agent follows three main steps: ### Step 1: Write the Prompt * Define agent identity and personality * Set style guardrails and conversation tone * Specify response guidelines * Outline tasks and procedures **[→ Learn More: Writing a Single Prompt](./write-prompt)** ### Step 2: Configure Basic Settings * Select voice and language * Configure call behavior (interruptions, delays, timeouts) * Set up noise cancellation and audio processing * Enable advanced features (gender detection, smart call end, etc.) **[→ Learn More: Configure Basic Settings](./configure-settings)** ### Step 3: Add Integrations (Optional) * Connect knowledge bases * Add custom tools and functions * Configure webhooks * Define outcome parameters **[→ Learn More: Knowledge Base](/agents/knowledge-base/introduction)** **[→ Learn More: Tools & Functions](/agents/tools/introduction)** **[→ Learn More: Webhooks](/agents/webhooks/introduction)** ## Example Use Cases ### Customer Support Bot Simple Q\&A agent that answers common questions using knowledge base: * **Preamble**: \~200 words defining personality and guidelines * **Knowledge Base**: FAQ documents and help articles * **Tools**: None or minimal (ticket creation) ### Appointment Scheduler Collects information and books appointments: * **Preamble**: \~300 words with booking procedure * **Tools**: Calendar availability check, booking function * **Variables**: Name, phone, date, time, service type ### Lead Qualification Gathers lead information and routes to sales: * **Preamble**: \~250 words with qualification questions * **Variables**: Company size, budget, timeline, needs * **Outcome**: Structured lead data ## Key Features ### Flexible Greeting Choose between static greetings for consistency or dynamic greetings that adapt to context (time of day, caller information, etc.). ### Advanced Call Settings * **Response Delay**: Control how quickly the agent responds (100-1500ms) * **Interruption Handling**: Allow or prevent user interruptions * **Inactivity Timeout**: Automatically handle silent callers (5–60 seconds) * **Max Call Duration**: Set maximum call length (30 seconds – 1 hour) ### Audio Processing * **Noise Cancellation**: Remove background noise (disabled, telephony optimized, or general use cases) * **Background Noise**: Add ambient sound for realism * **Thinking Voice**: Add natural pauses and filler words ### Intelligence Features * **Gender Detection**: Detect caller gender for personalized responses * **Smart Call End**: Automatically end calls when conversation concludes * **Language Dialect Switcher**: Adapt to caller's dialect * **Speaker Identification**: Identify different speakers on the same call * **Agentic RAG**: Advanced knowledge retrieval with reasoning ## Benefits ### ✅ Quick to Build Get started in minutes with a single comprehensive prompt. ### ✅ Easy to Maintain All agent behavior defined in one place makes updates simple. ### ✅ Cost-Effective Simpler architecture means lower latency and potentially lower costs. ### ✅ Perfect for MVPs Fastest path from idea to working agent. ## Limitations ### ⚠️ Limited Complexity Not suitable for highly branching conversation flows. ### ⚠️ Prompt Size Constraints Large prompts (>500 words) become harder to manage and may reduce performance. ### ⚠️ Less Control Cannot fine-tune behavior for specific conversation stages independently. ### ⚠️ Tool Limitations Best with 3 or fewer tools; more tools can confuse the agent. ## Template Structure Here's a recommended prompt structure: ``` ## Identity [Define who the agent is and what it represents] ## Style Guardrails [Set tone, personality, and conversation style] ## Response Guidelines [Specify how to format responses and handle edge cases] ## Task & Goals [Outline what the agent should accomplish] ## Objection Handling [Provide guidance for common objections or difficult scenarios] ``` **[→ See Full Template & Examples](./write-prompt)** ## Next Steps Ready to create your first single prompt agent? 1. **[Write Your First Prompt](./write-prompt)** - Learn prompt engineering best practices 2. **[Configure Settings](./configure-settings)** - Set up voice, timing, and behavior 3. **[Add Knowledge Base](/agents/knowledge-base/introduction)** - Enhance with company information 4. **[Test Your Agent](/agents/testing/introduction)** - Test in browser or via phone call *** **Need more power?** Check out **[Flow Agent Overview](../flow-agent/overview)** for complex conversation flows. # Voice Settings Source: https://docs.tryhamsa.com/agents/single-prompt/voice-settings Configure the voice, language, and dialect for your single prompt agent ## Overview Voice settings control how your agent sounds during calls. You can choose from Hamsa's library of AI voices, filter by language, dialect, gender, and style, and preview voices before selecting one. ## Accessing Voice Settings 1. Open your Single Prompt Agent 2. Expand the **Configuration** panel 3. Click **Voice Settings** to expand the section 4. Click **Change** to open the voice selector ## Voice Library The voice selector is organized into four tabs: * **All Voices** — Complete library of available voices * **Favorite Voices** — Voices you've starred * **Currently Used** — Voices recently used across your agents * **My Voices** — Custom voices created via voice cloning ## Filters Use filters to narrow down the library: **Language** — Select **English** or **Arabic**. Voices are language-specific; always match the voice language to your agent's conversation language. **Gender** — Filter by **Male**, **Female**, or show all. **Dialect** — Available for Arabic only. Options include Egyptian (EGY), Saudi Arabian (KSA), Emirati (UAE), Jordanian (JOR), Lebanese (LEB), Syrian (SYR), Palestinian (PLS), Iraqi (IRQ), and Bahraini (BAH). English does not have dialect sub-filters. **Style** — Filter by **Conversational** (natural, everyday tone) or **Narrator** (clear, broadcast-style delivery). **Search** — Type a voice name to filter in real time. Click **Clear Filters** to reset. ## Previewing and Selecting a Voice 1. Click the **Play** button on any voice card to hear a sample 2. Click the voice card to select it 3. Click **Save** to apply Preview samples are short clips. Always test your chosen voice in a real call using the Test Agent feature before going live. ## Managing Voices **Favorites** — Click the star icon on a voice card to add it to your Favorite Voices tab for quick access. **Copy Voice ID / Name** — Hover over a voice card, click the actions menu (⋯), and select **Copy ID** or **Copy Name**. Voice IDs are useful for API integrations. ## Voice Cloning You can create a custom branded voice and use it like any other voice in the library. See [Voice Cloning](/overview/features/voice-cloning) for details. ## Expressiveness Controls the emotional range and variation of the voice. **Range:** 0.0–2.0 (slider from Stable to Expressive) **Default:** 1.0 Lower values produce more stable, consistent speech. Higher values add more emotional variation and emphasis. ## Voice Dictionaries Attach pronunciation dictionaries for specialized terms — brand names, technical jargon, foreign words, or any term the default voice may mispronounce. Dictionaries are created and managed in the **Voices → Dictionaries** section, then selected here in Voice Settings. Click **Manage Dictionaries** to open the dictionaries page. ## STT Model Select the speech-to-text model for transcription. | Model | Description | | -------------------------- | ---------------------------------------- | | **Hamsa-STT-S2** (default) | Stable Arabic/English recognition | | **Hamsa-STT-S3-beta** | Most recent model, faster Arabic/English | | **Hamsa-STT-English** | English-focused recognition | Selecting **Hamsa-STT-English** automatically sets the user language to English. The other models support multilingual recognition. ## Language and Dialect Switcher The Language Dialect Switcher (enabled in **Call Settings**) adapts speech recognition to the caller's Arabic dialect, even if your agent is configured with a different Arabic dialect. For example, an agent configured with Egyptian Arabic can better understand a caller speaking Gulf Arabic when this is enabled. This feature is designed for Arabic dialect variation. English operates with a single general speech recognition model. ## Troubleshooting **Voice sounds robotic or unnatural** — Try a different voice. Make sure the voice language matches the agent's conversation language. **Voice is too fast or slow** — Speed is a characteristic of the voice itself and is not configurable. Try a different voice, or adjust sentence length in your prompt to influence pacing. **Voice sounds different in production vs preview** — Always test via Test Agent rather than relying on preview clips alone. **Can't find a previously used voice** — Check the **Currently Used** tab, or search by name. ## Next Steps Configure response timing, interruptions, and timeouts Enable gender detection, smart call end, and more Configure the AI model and temperature Create a custom branded voice # Writing Effective Prompts Source: https://docs.tryhamsa.com/agents/single-prompt/write-prompt How to write the preamble (system prompt) for your single prompt agent ## Overview The **preamble** is the system prompt that defines your agent's identity, behavior, and task. Everything the agent does during a call is guided by this prompt. ## Recommended Structure A well-structured preamble typically covers these sections: ### 1. Identity & Role Define who the agent is and what it represents. ``` You are Alex, a customer support specialist at Acme Corp. You help customers with product inquiries, order tracking, and technical support. ``` ### 2. Personality & Tone Set the conversation style. ``` Speak in a warm, friendly, and patient manner. Keep responses concise. ``` ### 3. Response Guidelines Specify how the agent should format and structure its responses. ``` - Keep responses under 30 seconds of speech - Ask one question at a time - Confirm understanding before proceeding - If you don't know something, say so honestly ``` ### 4. Task & Goals Define what the agent should accomplish, ideally as numbered steps. ``` Your primary task is to schedule appointments. Process: 1. Greet the caller 2. Collect: full name, phone number, preferred date and time 3. Check availability using the check_availability tool 4. Confirm the appointment details 5. Provide a confirmation number ``` ### 5. Guardrails Set clear boundaries for what the agent should not do. ``` Do NOT: - Make promises you cannot keep - Discuss competitor products - Process payments or collect card details - Continue if the user is abusive ``` ### 6. Edge Case Handling Prepare for difficult scenarios. ``` If asked something outside your knowledge: - Be honest: "I don't have that information available" - Offer alternatives: "I can transfer you to someone who can help" ``` ## Using Variables You can reference system variables and custom variables in your prompt using `{{variable_name}}` syntax. **System variables** (always available): | Variable | Description | | --------------------------- | ------------------------------- | | `{{agent_name}}` | Name of the current agent | | `{{agent_id}}` | Unique identifier for the agent | | `{{agent_number}}` | Agent's phone number | | `{{current_time}}` | Current time (HH:MM) | | `{{current_date}}` | Current date (YYYY-MM-DD) | | `{{current_datetime}}` | Date and time in ISO format | | `{{current_day}}` | Day of the month (1–31) | | `{{current_month}}` | Month (1–12) | | `{{current_year}}` | Year (YYYY) | | `{{current_weekday}}` | Day of the week | | `{{current_timestamp}}` | Timestamp in milliseconds | | `{{call_id}}` | Unique call identifier | | `{{call_type}}` | Type of call | | `{{call_start_time}}` | When the call began | | `{{direction}}` | `inbound` or `outbound` | | `{{user_number}}` | Caller's phone number | | `{{user_number_area_code}}` | Caller's area code | For dynamic business-specific data (e.g., working hours, customer info), use **custom variables** passed as `params` when initiating the call. See [Variable System](/agents/variables/introduction) for details. ### Jinja2 Templates Beyond simple substitution, prompts support full **Jinja2** template syntax — conditionals, filters, and expressions are all available. ``` {% if direction == "outbound" %} Hi {{customer_name}}, this is {{agent_name}} from Acme Corporation. {% else %} Thank you for calling Acme Corporation. I'm {{agent_name}}. {% endif %} ``` ``` Welcome{% if customer_name %}, {{customer_name}}{% endif %}! Your balance is {{balance | default("unavailable")}}. ``` Templates are processed server-side before the prompt reaches the LLM. See the [Jinja2 Template Designer Documentation](https://jinja.palletsprojects.com/en/stable/templates/) for the full syntax reference. **Example:** ```markdown theme={null} You are {{agent_name}}. Today is {{current_date}} and the time is {{current_time}}. The caller's number is {{user_number}}. Working hours: {{working_hours}} ``` ## Prompt Settings Below the prompt editor, two settings control how your prompt is processed: **Enhanced Turn Taking** — Enables better numeral capturing and backchannel detection for more natural conversations. Default: Off. **Prompt Enhancer** — Applies automatic enhancements to your prompt before it reaches the LLM: | Option | Description | | ------------------- | ------------------------------------------ | | **Disabled** | Your prompt is used as-is | | **Basic** (default) | Stable, model-agnostic prompt enhancements | | **Advanced** | Model-aware prompts with live context | ## Tool Integration When your agent uses tools, include clear instructions for when and how to use them: ```markdown theme={null} To check product availability: 1. Ask for the product name or SKU 2. Use the check_inventory tool 3. Based on results: - In stock: "We have that available. Would you like to place an order?" - Out of stock: "That's currently out of stock." - Discontinued: "That product has been discontinued. Can I suggest an alternative?" ``` ## Common Mistakes **Too vague:** ``` You are a helpful assistant. Answer questions. ``` **Better:** ``` You are a customer support specialist for Acme Corp. Help customers with product questions, order tracking, and returns. Use the knowledge base for product details. ``` *** **Conflicting instructions:** ``` Be extremely brief. Provide detailed, comprehensive answers with lots of context. ``` **Better:** ``` Give concise answers (2–3 sentences). If the customer wants more detail, offer to elaborate: "Would you like me to explain that further?" ``` ## Next Steps Configure voice and language options Set up response timing and interaction controls Enable smart features like gender detection and smart call end Add reference materials for your agent # Telephony Dashboard Guide Source: https://docs.tryhamsa.com/agents/telephony/introduction Manage phone numbers using the Hamsa dashboard Learn how to add, configure, and manage phone numbers for your AI agents using the Hamsa web interface. ## What You'll Learn * Adding phone numbers from different providers * Assigning numbers to agents * Configuring inbound call handling * Making test outbound calls * Managing SIP trunk connections ## Getting Started Navigate to the **Phone Numbers** page to add and manage telephony for your agents. For making outbound calls at scale and automating number management, see the [Telephony Integration Guide](/developers/guides/telephony-integration). ## Next Steps * Add your first phone number * Assign it to an agent * Test inbound and outbound calls # Testing Dashboard Guide Source: https://docs.tryhamsa.com/agents/testing/introduction Test and debug agents using the Hamsa dashboard Learn how to test and debug your AI agents using the browser and phone testing tools in the Hamsa web interface. ## What You'll Learn * Using browser testing for rapid iteration * Testing with real phone calls * Viewing real-time transcripts and logs * Monitoring variable extraction * Debugging conversation flows ## Getting Started Open your agent and click the **Test Agent** button to begin browser testing, or use **Test via Phone** for real phone call testing. For automated testing and CI/CD integration, see the [Testing Guide](/developers/guides/testing). ## Next Steps * Run your first browser test * Make a test phone call * Review test call transcripts # Function Tools Source: https://docs.tryhamsa.com/agents/tools/function-tools Make server-side API calls during conversations to extend your agent with external data and actions Function tools allow your agent to make HTTP requests to external APIs during a conversation. Use them to look up data, perform actions, or integrate with your backend systems. ## How They Work ``` User speaks → Agent decides to call a tool → Server makes API request → Response returned → Agent uses the data in its reply ``` Function tools run server-side, so they work on both phone and web deployments. ## Creating a Function Tool 1. Navigate to the **Tools** section in your dashboard 2. Click **Create Tool** 3. Select **API Request** as the tool type 4. Configure the tool: ### Basic Configuration * **Name**: A clear name the LLM uses to understand when to call the tool (e.g., `check_order_status`) * **Description**: Explain what the tool does — the LLM uses this to decide when to invoke it * **URL**: The API endpoint to call * **Method**: GET, POST, PUT, PATCH, or DELETE ### Parameters Define the parameters the agent should extract from the conversation and pass to the API: ```json theme={null} { "order_id": { "type": "string", "description": "The customer's order ID" }, "include_tracking": { "type": "boolean", "description": "Whether to include tracking information" } } ``` The agent will extract these values from the conversation context before making the call. ### Authentication * **None**: No authentication headers. * **Bearer Token**: Prepends `Bearer ` to the provided string and sends it in the `Authorization` header. * **Token**: Prepends `Token ` to the provided string. * **Basic Auth**: Enter a Username and Password; the system automatically Base64-encodes them into a single string (`user:pass`) and sends it as a `Basic` auth header. * **Custom Headers**: Manually define any other header name and value pair. ### Asynchronous Execution (Async) Toggle the **Async** setting to control how the agent waits for a response: * **Async OFF (Synchronous)**: The agent waits for the API response before proceeding. Use this when the agent needs the response data to decide what to say next or how to route the flow. * **Async ON (Asynchronous)**: The agent sends the request and immediately continues the conversation or moves to the next node without waiting. Use this for "fire-and-forget" actions like sending an SMS, starting a background export, or other slow background processes. ### Timeout Set a maximum wait time for the API response (in milliseconds). If the API doesn't respond in time, the tool call fails gracefully. ## Using Function Tools ### In Single Prompt Agents The agent decides when to call the tool based on the conversation and the tool's description. The API response (string or JSON) is sent back to the LLM, which uses it naturally in its next reply. **Example**: A customer asks "Where's my order?" → Agent calls `check_order_status` with the order ID → API returns tracking info → Agent relays the information conversationally. ### In Flow Agents Function tools are used via [Tool Nodes](/agents/flow-agent/nodes/tool-node). You can: * Extract specific values from the response using output mapping * Route the conversation based on extracted values using transitions * Use extracted data in subsequent nodes via variables ## Examples ### Order Status Lookup ``` Name: check_order_status Description: Check the current status and tracking information for a customer order Method: GET URL: https://api.yourstore.com/orders/{order_id} Parameters: - order_id (string, required): The order ID to look up ``` ### Appointment Booking ``` Name: book_appointment Description: Book an appointment for the customer at the requested date and time Method: POST URL: https://api.yourservice.com/appointments Parameters: - date (string, required): Appointment date in YYYY-MM-DD format - time (string, required): Appointment time in HH:MM format - service_type (string, required): Type of service requested ``` ### Customer Lookup ``` Name: find_customer Description: Look up a customer by their phone number or email address Method: GET URL: https://api.yourcrm.com/customers/search Parameters: - phone (string): Customer's phone number - email (string): Customer's email address ``` ## Related Overview of all tool types Using function tools in flow agents # Tools Source: https://docs.tryhamsa.com/agents/tools/introduction Extend your agent with server-side API calls, MCP integrations, and client-side web tools Tools allow your voice agent to perform actions during a conversation — calling APIs, querying databases, interacting with the user's browser, and more. ## Tool Types Hamsa supports three types of tools: ### Function Tools (API Requests) Server-side tools that make HTTP requests to external APIs during a conversation. Use these for: * Looking up customer data * Checking order status * Booking appointments * Any backend operation Function tools work on both phone and web deployments. Configure them in the **Tools** section of your dashboard. ### MCP Tools (Model Context Protocol) Server-side tools that connect to MCP-compatible services. Use these for integrating with external platforms that support the MCP standard. MCP tools work on both phone and web deployments. Configure them by connecting an MCP server in your dashboard. ### Web Tools (Client-Side) JavaScript functions that run in the user's browser when your agent is deployed via the [Voice Agents SDK](/developers/sdks/voice-agents-web-sdk). Use these for: * Navigating the user to a page * Opening modals or panels * Reading page data (cart contents, form values) * Interacting with your web application's UI Web tools only work on web deployments (SDK). They are registered in code via the SDK's `tools` parameter, not in the dashboard. For full details on web tools, including code examples and how they differ between single prompt and flow agents, see the [Web Tools documentation](/agents/tools/web-tools). ## Creating Tools Navigate to the **Tools** section in your dashboard to create function tools and MCP connections. For web tools, see the [Voice Agents SDK documentation](/developers/sdks/voice-agents-web-sdk) for how to register client-side functions. ## Tools in Single Prompt vs Flow Agents * **Flow Agent**: You can extract specific values from the tool's response using output mapping, and route the conversation based on those values using transitions. This applies to all tool types (function, MCP, and web tools). ## Tool Collections (Categorization) Hamsa uses a hierarchical collection system to keep your tools organized: * **System Collections**: * **All**: View every tool across the entire project. * **Uncategorized**: Tools not yet assigned to a custom folder. * **User Collections**: Create custom folders with specific names and descriptions to group related tools (e.g., "CRM Integration", "Internal Utilities"). Manage your collections using the sidebar in the Tools dashboard. You can create new folders and move tools between them to maintain a clean workspace. ## Versioning & Syncing The platform includes a backend-managed versioning system to track changes and ensure conversation stability. * **Persistent vs. Record IDs**: Each tool has a **Persistent ID** that stays constant across all updates, while the **Record ID** changes with every version. * **Auto-Increment**: Saving changes to a tool automatically creates a new version record with its own timestamp and optional changelog. * **Syncing Agents**: If an agent is using an older version of a tool, the dashboard will notify you. You can "Sync" the agent with a single click, which updates all tool references to the latest version. ## Tool Lifecycle Messages You can customize what the agent speaks at different stages of a tool's execution to create a smoother user experience. * **Request Start**: A message spoken as soon as the tool is triggered (e.g., *"One moment while I check your order status..."*). * **Request Complete**: A message spoken once the response is received. These messages are essential for "masking" API latency, ensuring there are no awkward silences in the voice conversation. ## Dashboard Management The Tools dashboard is designed for efficiency with several built-in management features: * **Global Search**: Instantly find tools by name or description using the debounced search bar. * **Status Filtering**: Quickly toggle between Active, Inactive, or All tools. * **Local Drafting**: The dashboard automatically saves your progress in `localStorage` keyed by collection. If you accidentally navigate away, you'll be prompted to restore your unsaved draft when you return. # MCP Tools Source: https://docs.tryhamsa.com/agents/tools/mcp-tools Connect to Model Context Protocol servers for external service integrations MCP (Model Context Protocol) tools connect your agent to external services that implement the MCP standard. This allows your agent to use capabilities provided by MCP-compatible servers during conversations. ## How They Work ``` User speaks → Agent decides to call an MCP tool → Request sent to MCP server → Server processes and responds → Agent uses the result in its reply ``` MCP tools run server-side, so they work on both phone and web deployments. ## Setting Up MCP Tools 1. Navigate to the **Tools** section in your dashboard 2. Click **Create Tool** 3. Select **MCP Server** as the tool type 4. Provide the MCP server connection details ### Connection Configuration * **Server URL**: The MCP server endpoint * **Authentication**: Credentials required by the MCP server (if any) Once connected, the available tools from the MCP server are automatically discovered and made available to your agent. ## Using MCP Tools ### In Single Prompt Agents The agent sees the MCP tools alongside any other configured tools. It decides when to call them based on the tool descriptions provided by the MCP server. The response is sent back to the LLM as context. ### In Flow Agents MCP tools are used via [Tool Nodes](/agents/flow-agent/nodes/tool-node), just like function tools. You can extract values from responses and route the conversation based on results. ## When to Use MCP Tools Use MCP tools when: * You have an existing MCP server you want to connect to * You want to leverage a third-party service's MCP integration * You need capabilities that are provided through the MCP ecosystem For custom API integrations where you control the endpoint, [Function Tools](/agents/tools/function-tools) are typically simpler to set up. ## Related Overview of all tool types Server-side API call tools # Web Tools Source: https://docs.tryhamsa.com/agents/tools/web-tools Client-side JavaScript functions that let your agent interact with your web application Web tools are JavaScript functions that run in the user's browser, allowing your agent to interact directly with your web application. They are registered via the [Voice Agents SDK](/developers/sdks/voice-agents-web-sdk) and triggered by the agent during conversation. Web tools only work when the agent is deployed via the Hamsa Voice Agents SDK. They do not function on phone calls. ## What Web Tools Can Do Since web tools run as JavaScript in the browser, they can do anything your web application can: * **Navigate the user** — take them to a specific page (e.g., "Show me the backpacks" → navigate to `/products/backpacks`) * **Open UI elements** — show a modal, expand a panel, trigger a popup * **Interact with the page** — scroll to a section, highlight an element, fill a form * **Read page data** — get the current URL, check cart contents, read form values * **Call client-side APIs** — access local storage, query IndexedDB, use browser APIs ## How They Work ``` User speaks → Agent decides to call a web tool → SDK triggers your registered function → Function runs in browser → Returns string or JSON → Response sent back to agent ``` ## Registering Web Tools Web tools are registered as JavaScript functions when starting a conversation via the SDK: ```javascript theme={null} const tools = [ { function_name: "navigate_to_page", description: "Navigate the user to a specific page on the website", parameters: [ { name: "path", type: "string", description: "The URL path to navigate to" } ], required: ["path"], fn: async (path) => { window.location.href = path; return "Navigated to " + path; } }, { function_name: "open_product_modal", description: "Open a product details modal for a specific product", parameters: [ { name: "productId", type: "string", description: "The product ID to display" } ], required: ["productId"], fn: async (productId) => { const product = await getProduct(productId); showProductModal(product); return JSON.stringify({ name: product.name, price: product.price }); } } ]; agent.start({ agentId: "YOUR_AGENT_ID", tools: tools, voiceEnablement: true }); ``` ## Return Values Web tools can return: * **A string** — simple confirmation sent back to the agent * **A JSON object** — structured data the agent (or flow) can use ```javascript theme={null} // String return — agent uses it conversationally fn: async (path) => { window.location.href = path; return "Done, the user is now on the backpacks page."; } // JSON return — can be extracted in flow agents fn: async (productId) => { const product = await getProduct(productId); return JSON.stringify({ name: product.name, price: product.price, inStock: product.available }); } ``` ## Behavior in Single Prompt vs Flow Agents ### Single Prompt Agents * The agent decides when to call the tool based on conversation context * The return value (string or JSON) is sent back to the LLM as-is * The model uses it as context for its next response * No structured extraction — the model interprets the response naturally ### Flow Agents * Web tools are used via [Web Tool Nodes](/agents/flow-agent/nodes/web-tool-node) * You can extract specific values from JSON responses using output mapping * The extracted values can be used in transitions to route the conversation * You can configure a processing message the agent speaks while the tool runs ```yaml theme={null} Web Tool Node: Check_Cart Output Mapping: cart_total: $.total item_count: $.items.length ↓ (Equation: {{cart_total}} > 100) Conversation Node: "Your cart total is {{cart_total}}. Would you like to checkout?" ↓ (Equation: {{cart_total}} <= 100) Conversation Node: "You have {{item_count}} items. Can I help you find anything else?" ``` ## Examples ### Website Navigation ```javascript theme={null} { function_name: "show_category", description: "Navigate the user to a product category page", parameters: [ { name: "category", type: "string", description: "Product category name" } ], required: ["category"], fn: async (category) => { const slug = category.toLowerCase().replace(/\s+/g, '-'); window.location.href = `/products/${slug}`; return `Showing ${category} products`; } } ``` ### Opening a Modal ```javascript theme={null} { function_name: "show_product_details", description: "Open a modal with detailed product information", parameters: [ { name: "productId", type: "string", description: "The product ID" } ], required: ["productId"], fn: async (productId) => { const product = await fetch(`/api/products/${productId}`).then(r => r.json()); document.getElementById('product-modal').showModal(); renderProductDetails(product); return JSON.stringify({ name: product.name, price: product.price }); } } ``` ### Reading Cart Data ```javascript theme={null} { function_name: "get_cart_summary", description: "Get the current shopping cart contents and total", parameters: [], required: [], fn: async () => { const cart = getCartFromLocalStorage(); return JSON.stringify({ items: cart.items.length, total: cart.total, currency: cart.currency }); } } ``` ### Form Submission ```javascript theme={null} { function_name: "submit_contact_form", description: "Submit the contact form with the provided details", parameters: [ { name: "name", type: "string", description: "Contact name" }, { name: "email", type: "string", description: "Email address" }, { name: "message", type: "string", description: "Message content" } ], required: ["name", "email", "message"], fn: async (name, email, message) => { const response = await fetch('/api/contact', { method: 'POST', body: JSON.stringify({ name, email, message }) }); return response.ok ? "Form submitted successfully" : "Submission failed"; } } ``` ## Versioning Like server-side tools, web tools are tracked via persistent IDs. When you register a tool in your SDK code, use the **Persistent ID** provided in the dashboard if you want to link it to a dashboard-managed tool record. This ensures that any call logs or analytics in the dashboard are correctly associated with the specific web tool. ## Related Overview of all tool types Using web tools in flow agent nodes Full SDK reference including tool registration Server-side API call tools # Advanced Features Source: https://docs.tryhamsa.com/agents/variables/advanced Nested data, enums, path selector, and technical architecture ## Nested Data Structures Variables can be objects or arrays with nested structure. **Object example:** ```typescript theme={null} { name: "user_profile", dataType: "object", properties: [ { name: "first_name", dataType: "string" }, { name: "last_name", dataType: "string" }, { name: "age", dataType: "number" }, { name: "is_verified", dataType: "boolean" } ] } ``` **Array example:** ```typescript theme={null} { name: "order_items", dataType: "array", item: { name: "item", dataType: "object", properties: [ { name: "product_id", dataType: "string" }, { name: "quantity", dataType: "number" }, { name: "price", dataType: "number" } ] } } ``` ## Enum Values Restrict a variable to a fixed set of options: ```typescript theme={null} { name: "appointment_type", dataType: "string", isEnumEnabled: true, enumValues: [ { value: "consultation", label: "Initial Consultation" }, { value: "follow_up", label: "Follow-up Visit" }, { value: "emergency", label: "Emergency Appointment" } ] } ``` **Benefits:** Consistent values, dropdown UI, better AI extraction, clearer validation. ## Variable Usage Tracking The system can track where variables are used: * Which nodes reference each variable * Which fields contain references * Count per field and last usage **Use cases:** Find unused variables, impact before deletion, refactoring, dependency view. ## JSONPath Path Selector (Tool Extraction) For tool nodes, the path selector lets you pick extraction paths from the response instead of typing JSONPath by hand. **Typical workflow:** 1. **Configure tool** (endpoint, headers, params). 2. **Test tool** (API: “Test Tool”; Web: define expected response). 3. **Add extracted variable** → open path selector. 4. **Browse tree** (expand/collapse, hover for types/values). 5. **Click a field** → JSONPath is filled (e.g. `$.data.user.email`). 6. **Preview** shows the extracted value; save when correct. **Features:** Test-before-extract (API), tree view, click-to-select, validation against response, preview, array and nested support, clear errors for invalid paths. **Example:** ``` Tool response has: data.user.email = "customer@example.com" Path selector: data → user → email (click) Selected path: $.data.user.email Extracted value: "customer@example.com" ``` ## Technical Architecture ### Store Structure **Variables store** holds: `extractedVariables`, `systemVariables`, `customVariables`, `referencedVariables`, `nodeAvailabilityCache`, `cacheVersion`, `isRecalculating`, `validationErrors`. ### Key Utilities * **Variable context**: `getVariableAvailabilityForNode()`, `analyzeFlowExecutionOrder()`, path analysis * **JSONPath mapper**: `userToBackendPath()` (`$.path` → `result.path`), `backendToUserPath()` * **Variable detection**: Scan text for `{{...}}`, extract names, validate syntax * **Context rules**: Pattern-based recommendations and context-aware suggestions ### Integration Flow builder store, variables store, flow–variables bridge, variable context utils, context rules, template system, validation, UI (panel, inputs, builders). ### Synchronization Flow ``` Flow change (node add/update/delete) → Flow–variables bridge → syncExtractedVariablesFromNodes() → Scan nodes for extractVariables, staticVariables, dtmfInputCapture → Update store, invalidate cache → UI re-renders ``` See [API Reference](./api-reference) for schemas and file paths, and [Extracted Variables](./extracted-variables) for using the path selector with API vs Web tools. # API Reference & Migration Source: https://docs.tryhamsa.com/agents/variables/api-reference Variable schemas, file locations, and migration from legacy ## Variable Schema ```typescript theme={null} interface Variable { id: string; name: string; // snake_case description?: string; dataType: DataType; // 'string' | 'number' | 'boolean' | 'array' | 'object' enumValues?: EnumValue[]; isEnumEnabled?: boolean; isRequired?: boolean; defaultValue?: any; extractionPrompt?: string; sourceNodeId?: string; sourceNodeType?: string; properties?: Variable[]; // object item?: Variable; // array } ``` ## Static Variable Schema ```typescript theme={null} interface StaticVariable { id: string; name: string; description?: string; dataType: DataType; value: any; // may include {{variable_name}} } ``` ## Data Types ```typescript theme={null} type DataType = 'string' | 'number' | 'boolean' | 'array' | 'object'; ``` ## Enum Value Schema ```typescript theme={null} interface EnumValue { value: string; label?: string; } ``` ## File Locations **Stores:**\ `variables.store.ts`, `flow-variables-bridge.ts`, `variable.schemas.ts`, `node.schemas.ts` under `src/features/agents/flow-builder/` (stores, schemas). **Utils:**\ `variable-context.ts`, `variable-context-rules.ts`, `jsonpath-mapper.ts`, `variable-detection.ts` under `src/features/agents/flow-builder/utils/`. **Components:**\ Variables panel, variables card, static variables builder, variable text input, variables builder under `src/features/agents/flow-builder/components/`. **Hooks:**\ `use-variable-context.ts`, `use-variable-categories.ts`, `use-global-variable-validation.ts` under `src/features/agents/flow-builder/hooks/`. ## Migration from Legacy Variable System 1. **System variables:** Map old names to current system variables. 2. **Extracted variables:** Update to new extraction config format. 3. **Custom variables:** Move workflow-level variables into custom variables. 4. **Static variables:** Map node-level constants to static variables. 5. **Validation:** Run validation and fix any errors. 6. **Testing:** Re-test all flows and single-prompt agents. ### Breaking Changes * Node-specific context variables (e.g. `conversation_history`, `tool_response`) are no longer used. * Availability is strictly by flow execution order. * Global nodes cannot use extracted or static variables. * JSONPath in the UI uses `$.` (still converted to `result.` in the backend). *** **Last updated:** February 2026 · **Version:** 2.0 # Availability & Context Source: https://docs.tryhamsa.com/agents/variables/availability-and-context Where variables are available in flow and single-prompt agents Variable availability depends on **agent type** and **flow position**. The system uses flow analysis to decide which variables each node (or single prompt) can use. ## Availability by Variable Type | Variable Type | Global Nodes | Regular Nodes | Single-Prompt Agent | Logic | | ------------------- | ------------ | ------------- | ------------------- | --------------------------- | | System Variables | ✅ Yes | ✅ Yes | ✅ Yes | Always available | | Custom Variables | ✅ Yes | ✅ Yes | ✅ Yes | Always available | | Extracted Variables | ❌ No | ✅ Yes\* | ❌ No | Only from predecessor nodes | | Static Variables | ❌ No | ✅ Yes\* | ❌ No | Only from predecessor nodes | \* Only if the current node runs **after** the node that created the variable. ## Flow Position Rules (Flow Agent) 1. **Predecessors only**: A node sees variables only from nodes that run before it. 2. **Execution paths**: All possible paths are considered when computing predecessors. 3. **Global nodes**: Nodes with `isGlobal: true` see only **system** and **custom** variables. 4. **Caching**: Availability is cached per node and refreshed when the flow changes. ## Example Flow ``` Start Node (creates: user_number) ↓ Conversation Node (creates: customer_name, appointment_date) ↓ Tool Node (creates: booking_id, confirmation_code) ↓ End Node Available at each step: - Start Node: system, custom - Conversation Node: system, custom, user_number - Tool Node: system, custom, user_number, customer_name, appointment_date - End Node: system, custom, user_number, customer_name, appointment_date, booking_id, confirmation_code ``` ## Single Prompt Agent Variables Single prompt agents are standalone conversational agents that don't use the flow builder. They have a simplified variable model optimized for quick deployment and simple use cases. ### Variable Availability | Variable Type | Available | Notes | | ------------------- | --------- | -------------------------------------- | | System Variables | ✅ Yes | All 15+ platform variables available | | Custom Variables | ✅ Yes | Converted to `params` in configuration | | Extracted Variables | ❌ No | No flow nodes to extract from | | Static Variables | ❌ No | No nodes to define static variables | ### How Custom Variables Work in Single Prompt Agents Custom variables in single prompt agents act as **parameters** that configure the agent: **Definition (Variables Panel):** ``` Custom Variables: - business_name: "Acme Corporation" - support_email: "support@acme.com" - max_conversation_turns: 10 - enable_transfers: true ``` **Conversion to params:** ```typescript theme={null} // Custom variables become params in agent configuration { params: { business_name: "Acme Corporation", support_email: "support@acme.com", max_conversation_turns: 10, enable_transfers: true } } ``` **Usage in prompt:** ``` You are a customer service agent for {{business_name}}. If customers need help, direct them to {{support_email}}. Keep conversations under {{max_conversation_turns}} turns. {{#if enable_transfers}}You can transfer calls to human agents.{{/if}} ``` ### Key Differences from Flow Builder Agents | Aspect | Flow Builder Agents | Single Prompt Agents | | ---------------- | ------------------------------------ | ---------------------------- | | Complexity | Multi-node workflows | Single prompt configuration | | Variables | System + Custom + Extracted + Static | System + Custom only | | Extraction | AI extraction, toolpath, DTMF | Not supported | | Flow Logic | Conditional branching, loops | Linear conversation | | Custom Variables | Workflow-level state | Configuration parameters | | Use Case | Complex workflows | Simple conversational agents | ### Use Cases for Single Prompt Agents **Good for:** * Simple Q\&A agents * Information lookup agents * Basic customer service * FAQ bots * Quick prototypes * Agents with minimal state **Not good for:** * Multi-step workflows * Data collection and processing * API integrations with variable extraction * Complex conditional logic * State management across multiple steps ### Configuration Example **Variables Panel (Custom Variables):** ``` working_hours: "9 AM - 5 PM EST" support_tier: "premium" escalation_enabled: true ``` **Single Prompt Configuration:** ``` System Prompt: You are {{agent_name}}, a helpful assistant. Our working hours are {{working_hours}}. Current time: {{current_time}} Current date: {{current_date}} Instructions: - Be friendly and professional - Answer questions about our products {{#if escalation_enabled}} - Offer to escalate complex issues to human agents {{/if}} User's phone: {{user_number}} Call direction: {{direction}} ``` **Available variables in this example:** * ✅ `working_hours`, `support_tier`, `escalation_enabled` (custom) * ✅ `agent_name`, `current_time`, `current_date`, `user_number`, `direction` (system) ### When to Upgrade to Flow Builder Consider upgrading to a Flow Builder agent when you need to: * Extract data from conversations (AI extraction) * Integrate with APIs and parse responses (toolpath extraction) * Use conditional branching or multi-step logic * Collect structured information across nodes * Use DTMF capture or static variables For DOs and DON'Ts specific to single prompt agents, see [Best Practices: Single Prompt Agent Variables](./best-practices#single-prompt-agent-variables). ## Variable Categories & Display Variables are grouped for the UI: | Category | Icon | Contains | | --------- | ---- | ------------------------------- | | System | 🔧 | Platform variables | | Custom | ⚙️ | Workflow-level variables | | Extracted | 📤 | From nodes (AI, toolpath, DTMF) | | Static | 📌 | Node-level set values | Displayed per variable: **name**, **type**, **source** (for extracted/static), **description**, **default/example value**. ## Context-Aware Recommendations The UI can suggest variables based on node type and content: * **Conversation**: e.g. `customer_name`, `phone_number`, `appointment_date`, `issue_description` * **Tool**: e.g. `api_response`, `status_code`, `response_data`, `error_message` * **Transfer**: e.g. `transfer_reason`, `customer_context`, `conversation_summary` See [UI Components & Validation](./ui-and-validation) for where these appear and [Introduction](./introduction) for the overall model. # Best Practices Source: https://docs.tryhamsa.com/agents/variables/best-practices Guidance for working with variables This page covers key constraints and patterns for variables. Additional best practices from the Hamsa engineering team will be added here over time. ## Variable Naming All variable names must be **snake\_case** (lowercase letters, underscores, starting with a letter): ``` ✅ customer_name ✅ account_balance ✅ is_verified ❌ customerName (camelCase not accepted) ❌ Customer-Name (kebab-case not accepted) ❌ customer name (spaces not accepted) ``` ## Extraction Availability Extracted variables are only available **after** the node that collects them. Do not reference an extracted variable in a transition or node that comes before it in the flow. Global node conditions cannot reference extracted variables — use system variables or custom variables there instead. ## Single Prompt Agents Custom variables are the only type available in single prompt agents. Extracted variables and static variables are not supported. Custom variables become `params` in the agent configuration and must be passed when initiating a call. ## Testing Tool Extraction Always test a tool call first to see its actual response before configuring extraction. Use the path selector to pick JSONPath expressions from the real response — avoid writing JSONPath by hand. *** ## Next Steps Define variables in your agent configuration Collect data from conversations and tool responses Diagnose common variable issues See full flow examples with variables # Custom Variables Source: https://docs.tryhamsa.com/agents/variables/custom-variables Workflow-level variables for flow and single-prompt agents Custom variables are defined at the **workflow level** and are available to all nodes (flow agent) or to the single prompt (single-prompt agent). They are ideal for configuration, defaults, and passing caller-specific data. ## Characteristics * **Scope**: Global to the workflow (all nodes in flow agent; entire prompt in single-prompt agent) * **Where to define**: Variables panel at workflow level * **Default values**: Any supported data type * **Reference syntax**: `{{variable_name}}` * **Single-prompt agents**: Custom variables are exposed as `params` in the agent configuration ## When to Use * Values that change per deployment (e.g. business name, support email) * Default messages or responses * State or configuration shared across the flow * **Single-prompt agents**: Any data you want to pass into the prompt as parameters ## Example Use Cases ``` business_name: "Acme Corporation" support_email: "support@acme.com" max_retry_attempts: 3 is_after_hours: false ``` ## Flow Builder vs Single Prompt Agents | Aspect | Flow Builder Agent | Single Prompt Agent | | ----------------- | ----------------------------------- | ------------------------------------------------------------------- | | Available | All nodes, including global | Entire prompt | | Definition | Variables panel | Variables panel (stored as `params`) | | Usage | `{{variable_name}}` in node configs | `{{variable_name}}` in prompt; custom vars become `params` | | Conditional logic | Flow transitions, router nodes | `{{#if variable_name}}` in prompt (e.g. `{{#if enable_transfers}}`) | In single prompt agents, custom variables are the **only** user-defined variables; there are no extracted or static variables. See [Single Prompt Agent Variables](./availability-and-context#single-prompt-agent-variables) for availability, configuration examples, and when to upgrade to Flow Builder. See [Template Syntax & Naming](./syntax-and-naming) for naming and syntax. # Practical Examples Source: https://docs.tryhamsa.com/agents/variables/examples Example flows using variables—booking, routing, DTMF, tool testing, web tools, single-prompt agent ## Example 1: Appointment Booking (Flow Agent) **Goal:** Collect details in a conversation, call a booking API, then confirm. **Variables:** * **Custom:** `business_name`, `business_phone` * **AI extracted (Conversation):** `customer_name`, `appointment_date`, `appointment_time` * **Toolpath (Tool – Booking API):** After **Test Tool**, use path selector for `booking_id` (`$.data.booking.id`), `confirmation_code` (`$.data.booking.confirmation_code`) * **Static (Confirmation node):** `confirmation_message` = `"Your appointment at {{business_name}} is confirmed for {{appointment_date}} at {{appointment_time}}. Confirmation code: {{confirmation_code}}"` **Flow:** Start → Conversation (collect) → Tool (book) → Conversation (confirm) → End. Each step sees system + custom + variables from previous steps. ## Example 2: Customer Support Routing (Flow Agent) **Goal:** Classify issue and urgency, look up account, then route. **Variables:** * **Custom:** `support_hours_start`, `support_hours_end`, `emergency_number` * **AI extracted:** `issue_type` (enum: billing, technical, general), `urgency_level` (low, medium, high, critical) * **Toolpath (CRM):** `account_status`, `is_premium`, `customer_id` * **Static:** `routing_decision` = `"{{issue_type}}_{{urgency_level}}_{{account_status}}"` Use these in router conditions and transfer nodes. ## Example 3: DTMF Account Verification (Flow Agent) **Goal:** Capture account number via keypad, call account API, then speak balance or failure. **Variables:** * **DTMF (Start):** `account_number` * **Toolpath (Account API):** `account_verified`, `account_name`, `account_balance` * **Static:** `verification_success_message` and `verification_failure_message` using `{{account_name}}`, `{{account_balance}}`, `{{account_number}}` ## Example 4: API Tool Testing & Extraction (Flow Agent) **Goal:** Call a weather API and use response in the next message. **Steps:** 1. Configure tool (URL, params e.g. `{{user_location}}`, headers). 2. Click **Test Tool** with e.g. `user_location = "New York"`. 3. In path selector: pick `$.current.temperature` → `current_temperature`, `$.current.conditions` → `weather_conditions`, `$.location.city` → `city_name`, `$.forecast[0].high` → `tomorrow_high`. 4. In the next conversation node: `"The current temperature in {{city_name}} is {{current_temperature}}°C with {{weather_conditions}}. Tomorrow's high will be {{tomorrow_high}}°C."` **Takeaways:** Test first, use path selector, test success and error responses, handle optional fields. ## Example 5: Web Tool Variable Extraction (Flow Agent) **Goal:** Add to cart via web tool and confirm in a message. **Steps:** 1. Define **expected response** (object or string). Example object: `{"cart": {"total": 149.99, "item_count": 2, "items": [...], "discount_code": "SAVE10"}}`. 2. In path selector (against that structure): `$.cart.total` → `cart_total`, `$.cart.item_count` → `cart_item_count`, `$.cart.items[0].name` → `first_item_name`, `$.cart.discount_code` → `discount_code`. 3. For string response, use `$` for the full string (e.g. `cart_summary`). **Message:** `"I've added {{first_item_name}} to your cart. Total: ${{cart_total}}, {{cart_item_count}} items. Code: {{discount_code}}."` **Web vs API:** Web tools run in the browser; you define expected response and optionally test manually. API tools use **Test Tool** and real response for path selection. ## Example 6: Single Prompt Agent with Variables **Goal:** Create a simple customer support agent for a restaurant using a single prompt agent (no flow builder). **Agent type:** Single Prompt Agent **Step 1: Define custom variables** In the Variables Panel, create custom variables that act as configuration parameters: ``` restaurant_name: "Bella Italia" restaurant_phone: "+1 (555) 123-4567" restaurant_address: "123 Main Street, New York, NY" opening_time: "11:00 AM" closing_time: "10:00 PM" accepts_reservations: true delivery_available: true menu_url: "https://bellaitalia.com/menu" ``` **Step 2: Configure the single prompt** **System prompt:** ``` You are a friendly customer service assistant for {{restaurant_name}}. Restaurant Information: - Phone: {{restaurant_phone}} - Address: {{restaurant_address}} - Hours: {{opening_time}} to {{closing_time}} - Menu: {{menu_url}} Current Context: - Current time: {{current_time}} - Current date: {{current_date}} - Day of week: {{current_weekday}} - Customer phone: {{user_number}} Services: {{#if accepts_reservations}} - We accept reservations. You can help customers book tables. {{/if}} {{#if delivery_available}} - We offer delivery service. {{/if}} Your Role: - Answer questions about our menu, hours, and location - Help with reservations and orders - Be warm, friendly, and professional - If you don't know something, offer to have someone call them back ``` **Step 3: Available variables** **Custom (configuration):** `restaurant_name`, `restaurant_phone`, `restaurant_address`, `opening_time`, `closing_time`, `accepts_reservations`, `delivery_available`, `menu_url` **System:** `current_time`, `current_date`, `current_weekday`, `user_number`, `call_id`, `direction`, and all other system variables **Not available:** Extracted variables, static variables, or variables from conversation history (single prompt agents don’t have flow nodes). **Step 4: Example conversation** **User:** "What time do you close?" **Agent (using variables):** *"We're open from `{{opening_time}}` to `{{closing_time}}`. Right now it's `{{current_time}}`, so we're currently open!"* **Rendered:** *"We're open from 11:00 AM to 10:00 PM. Right now it's 2:30 PM, so we're currently open!"* **Step 5: Updating configuration** To change hours, update only the custom variables (e.g. `opening_time`, `closing_time`). The agent uses the new values without changing the prompt. **Step 6: Multi-environment** Use different custom variable values per location (e.g. NYC vs Boston: different `restaurant_name`, `restaurant_phone`, `restaurant_address`). Same prompt, different configuration. **Advantages of single prompt agents:** Simple setup, quick deployment, easy updates via variables, multi-environment support, no extraction needed for simple Q\&A. **When to upgrade to Flow Builder:** When you need to collect customer info, check availability via API, process orders, transfer by intent, or extract structured data from conversations. **Takeaways:** Custom variables act as configuration; system variables are available; no extraction; use `{{variable_name}}` and `{{#if}}` for conditionals; ideal for straightforward conversational agents and multi-environment configs. *** See [Extracted Variables](./extracted-variables) for AI/toolpath/DTMF details, [Availability & Context](./availability-and-context) for flow position and [Single Prompt Agent Variables](./availability-and-context#single-prompt-agent-variables), and [Best Practices](./best-practices) for naming and extraction strategy. # Extracted Variables Source: https://docs.tryhamsa.com/agents/variables/extracted-variables AI, toolpath, and DTMF extraction in flow agents Extracted variables are **flow-agent only**. They are created by nodes during execution from user input, tool responses, or DTMF and are available to successor nodes. ## Types of Extraction ### 1. AI Extracted Variables (Conversation Nodes) AI extraction uses LLM function calling to pull structured data from the conversation using natural language instructions. **Configuration:** * **Extraction Method**: `llm_function_calling` * **Extraction Prompt**: Natural language description of what to extract * **Data Type**: string, number, boolean, array, or object * **Required**: Whether the node depends on this extraction succeeding **Example:** ``` Variable: customer_name Extraction Prompt: "Extract the customer's full name from their response" Data Type: string Required: true ``` **Supported Data Types:** string, number, boolean, array, object **Advanced:** Enum values, nested objects, array item types ### 2. Toolpath Extracted Variables (Tool & Web Tool Nodes) Toolpath extraction uses JSONPath to pull values from tool response data. **Configuration:** * **User format**: `$.path.to.value` (JSONPath) * **Backend format**: `result.path.to.value` (converted automatically) * **Validation**: Against actual (API) or expected (Web) response * **Response format**: JSON object or plain string **JSONPath examples:** ``` $.data.user.email → Nested field $.items[0].name → First item $.results[*].id → All IDs $.data.prices[?(@.active)] → Filter $ → Entire response (for string) ``` **Response formats:** 1. **Object (JSON):** Use paths like `$.data.user`, `$.data.items[0]` 2. **String:** Use `$` to get the full string #### API Tool Nodes 1. Click **Test Tool** to run with real data 2. Use the **path selector** on the actual response 3. Browse the tree, click a field to set the JSONPath 4. Check the preview and save #### Web Tool Nodes Web tools run in the browser and can’t be tested server-side: 1. **Define expected response**: Paste JSON object or string 2. Open the **path selector** and use that structure 3. Click fields to set paths and preview 4. Manually test the web tool to confirm the real response matches **Example expected response (object):** ```json theme={null} { "cart": { "total": 149.99, "items": [{"name": "Product A", "price": 49.99}], "item_count": 2 } } ``` Or as string: `"Successfully added 2 items to cart. Total: $149.99"` **Best practices:** * **API**: Test first, then configure extraction; test success and error shapes * **Web**: Define a realistic expected structure; document object vs string; test manually ### 3. DTMF Captured Variables (Conversation & Start Nodes) DTMF capture creates a variable from keypad input (0-9, \*, #). **Configuration:** * **Enable DTMF Capture**: Toggle in node settings * **Variable Name**: Name for the captured value * **Sync**: Automatically added to extracted variables **Characteristics:** Always string; when enabled, number-key DTMF transitions are disabled for that node. **Example:** ``` Variable: account_number DTMF Capture: Enabled Description: "DTMF captured input" ``` ## Extraction Availability Extracted variables are available only to **successor nodes**: * ✅ Nodes that run after the node that created the variable * ❌ Nodes that run before or in parallel * ❌ Global nodes (`isGlobal: true`) See [Availability & Context](./availability-and-context) for full rules and [Advanced Features](./advanced) for the path selector and nested/array types. # Variable System Overview Source: https://docs.tryhamsa.com/agents/variables/introduction Variables for flow builder and single-prompt agents—overview, quick start, and architecture ## Overview This document covers the variable system used across all agent types. Variables enable dynamic data flow so you can capture, transform, and use data in your conversational agents. **Applies to:** * **Flow Builder Agents**: Multi-node workflows with variable extraction (AI, toolpath, DTMF), static variables, and flow logic * **Single Prompt Agents**: Standalone conversational agents with a simplified variable model (system + custom only) Variables provide context, enable personalization, and allow data to flow between parts of your agent—whether across nodes in a flow or within a single prompt configuration. ## Quick Start: Tool Testing & Variable Extraction The steps below apply to **Flow Builder agents** only (tool nodes and variable extraction). Single prompt agents use only system and custom variables—see [Single Prompt Agent Variables](./availability-and-context#single-prompt-agent-variables) and [Example 6: Single Prompt Agent](./examples#example-6-single-prompt-agent-with-variables). ### For API Tool Nodes (Flow Builder) 1. ⚙️ **Configure Tool** → Set up endpoint, headers, parameters 2. 🧪 **Test Tool** → Click "Test Tool" to run with real data 3. ✅ **Verify Response** → Confirm the tool returns the expected shape 4. 📤 **Extract Variables** → Use the path selector with the test response 5. 👁️ **Preview Values** → Check that extracted values are correct 6. 💾 **Save** → Variables are available to successor nodes **Why this matters:** Validates the API before deployment, avoids JSONPath mistakes, and surfaces issues at design time. ### For Web Tool Nodes (Flow Builder) 1. ⚙️ **Configure Web Tool** → Set up browser instructions and actions 2. 📋 **Define Expected Response** → Paste or type the expected structure (JSON object or string) 3. 📤 **Extract Variables** → Use the path selector against that expected structure 4. 👁️ **Preview Values** → Confirm extraction paths 5. 🧪 **Manually Verify** → Run the web tool to confirm the real response format 6. 💾 **Save** → Variables are available to successor nodes **Why this matters:** Documents the response contract, supports JSON and string responses, and lets you use the path selector without server-side testing. > **Important** > > * **API tools**: Test before configuring extraction; the path selector uses the actual test response. > * **Web tools**: Define the expected response; the path selector validates against that format. ## Variable Architecture The system has four main categories: | Category | Flow Builder Agents | Single Prompt Agents | Description | | ----------------------- | ------------------- | -------------------- | ------------------------------------------------------- | | **System Variables** | ✅ | ✅ | Platform-provided, always available (15+ variables) | | **Custom Variables** | ✅ | ✅ (as `params`) | Workflow-level; in single-prompt, converted to `params` | | **Extracted Variables** | ✅ | ❌ | From nodes (AI, toolpath, DTMF)—flow only | | **Static Variables** | ✅ | ❌ | Node-level, fixed or templated—flow only | ## Jinja2 Template Support Prompts support the full **Jinja2** template language. This is not a partial implementation or a JavaScript approximation — templates are rendered by a real Python Jinja2 engine running server-side, before the prompt ever reaches the LLM. The LLM receives plain text; it never sees template syntax. Beyond simple `{{variable_name}}` substitution, you can use: * **Conditionals** — `{% if direction == "outbound" %}...{% else %}...{% endif %}` * **Filters** — `{{ customer_name | default("there") | upper }}` * **Local variables** — `{% set greeting = "Hello" %}` * **Expressions** — any standard Jinja2 expression For the full syntax reference, see the [Jinja2 Template Designer Documentation](https://jinja.palletsprojects.com/en/stable/templates/). ### Template Editor When writing templates in the flow agent, prompts open in an **Expert Mode** editor with full Jinja2 tooling: * **Syntax highlighting** — Jinja2 tags, variables, and filters are visually distinguished from plain text * **Autocomplete** — press `{` to get snippet suggestions for `{{ }}` and `{% %}` blocks; inside a block, your available variables and all Jinja2 keywords and filters are suggested automatically * **Real-time linting** — undefined variables are flagged immediately with a warning; if it looks like a typo, the editor suggests the correct variable name and offers a one-click fix * **Type-aware property suggestions** — if a variable is typed as a string, array, or object, the editor suggests relevant properties and methods (`.length`, `| join`, `.first`, etc.) * **Smart block closing** — the editor detects open `{% if %}` or `{% for %}` blocks and suggests the correct closing tag * **Live preview** — supply test values for your variables and see the fully rendered output in real time, exactly as the LLM will receive it; syntax and runtime errors are surfaced immediately with the affected line number See [Prompt Engineering Guide](/overview/guides/prompt-engineering) for examples. ## Next steps * [System Variables](./system-variables) — Time, call, user, and agent variables * [Custom Variables](./custom-variables) — Workflow-level variables for both agent types * [Extracted Variables](./extracted-variables) — AI, toolpath, and DTMF extraction (flow only) * [Static Variables](./static-variables) — Node-level values (flow only) * [Availability & Context](./availability-and-context) — Where each type is available, including [Single Prompt Agent Variables](./availability-and-context#single-prompt-agent-variables) # Static Variables (Local Variables) Source: https://docs.tryhamsa.com/agents/variables/static-variables Node-level variables with fixed or templated values in flow agents Static variables are **flow-agent only**. They are set at the node level with fixed or templated values and are available to that node and its successors. ## Characteristics * **Scope**: Node-level; visible to successor nodes * **Where to define**: In the node’s configuration * **Value types**: string, number, boolean, array, object * **Templates**: Values can use `{{variable_name}}` to reference other variables * **Sync**: Stored in the variable store so availability is tracked correctly ## Supported Data Types | Data Type | Example Value | Use Case | | --------- | ----------------------------------- | ------------------------------- | | `string` | `"Hello {{customer_name}}"` | Text with variable substitution | | `number` | `42` or `{{max_attempts}}` | Numbers or references | | `boolean` | `true` or `false` | Flags and toggles | | `array` | `["option1", "option2", "option3"]` | Lists of values | | `object` | `{"key": "value", "count": 5}` | Structured data | ## Example Use Cases **1. Computed / formatted messages** ``` Variable: greeting_message Value: "Hello {{customer_name}}, welcome to {{business_name}}!" Data Type: string ``` **2. Configuration objects** ``` Variable: api_config Value: {"timeout": 5000, "retries": 3} Data Type: object ``` **3. Default lists** ``` Variable: available_options Value: ["Schedule", "Cancel", "Reschedule"] Data Type: array ``` **4. Flags** ``` Variable: is_premium_user Value: true Data Type: boolean ``` Static variables are **not** available in global nodes or in single-prompt agents. See [Availability & Context](./availability-and-context) and [Extracted Variables](./extracted-variables) for how they fit with other variable types. # Template Syntax & Naming Source: https://docs.tryhamsa.com/agents/variables/syntax-and-naming Variable reference syntax and naming rules ## Variable References Use double curly braces in text fields: ``` {{variable_name}} ``` ### Valid Examples ``` "Hello {{customer_name}}, your appointment is at {{appointment_time}}" "Your order #{{order_id}} will arrive on {{delivery_date}}" ``` ### Invalid Examples ``` {user_input} ❌ Single braces {{User Input}} ❌ Spaces {{user-input}} ❌ Hyphens {{userInput}} ❌ camelCase not allowed {{ user_input }} ❌ Spaces inside braces ``` ### Template Validation The system checks: * **Existence**: Referenced variable exists * **Syntax**: Valid `{{name}}` form * **Types**: Value matches declared type where relevant * **Availability**: Variable is available at the current node (flow agent) ## Naming Conventions All variables must follow these rules: ### Rules 1. **Format**: `snake_case` only 2. **Start**: Lowercase letter (a–z) 3. **Characters**: Lowercase letters, digits, underscores 4. **Length**: 1–50 characters 5. **Reserved**: Do not reuse system variable names ### Valid Examples ``` customer_name ✅ appointment_date_1 ✅ user_phone_number ✅ api_response_data ✅ is_premium_user ✅ ``` ### Invalid Examples ``` customerName ❌ camelCase Customer_Name ❌ Capital letters customer-name ❌ Hyphens customer name ❌ Spaces 123_customer ❌ Starts with number _customer_name ❌ Starts with underscore customer_name! ❌ Special characters ``` See [System Variables](./system-variables) for reserved names and [Validation](./ui-and-validation) for how errors are shown. ## Jinja2 Template Syntax Prompts support full **Jinja2** template syntax beyond simple `{{variable_name}}` substitution. You can use conditionals, filters, and any standard Jinja2 expression: ``` {% if direction == "outbound" %} Hi {{customer_name}}, I'm calling from Acme Corporation. {% else %} Thanks for calling! How can I help you today? {% endif %} ``` ``` Your balance is {{balance | default("unavailable")}}. ``` Templates are processed server-side — the LLM receives the rendered output, not the template. For the full syntax reference including all filters, tests, and operators, see the [Jinja2 Template Designer Documentation](https://jinja.palletsprojects.com/en/stable/templates/). # System Variables Source: https://docs.tryhamsa.com/agents/variables/system-variables Platform-provided variables for time, call, user, and agent System variables are built-in and always available in **flow agents** and **single-prompt agents**. They provide call context, time, and user/agent details. ## Time Variables | Variable | Type | Description | Example Value | | ------------------- | ------ | ------------------------------ | ------------------------- | | `current_time` | string | Current time in HH:MM format | `"14:30"` | | `current_date` | string | Current date in locale format | `"1/15/2026"` | | `current_datetime` | string | Current date and time | `"1/15/2026, 2:30:00 PM"` | | `current_timestamp` | string | Unix timestamp in milliseconds | `"1737820200000"` | | `current_day` | string | Day of the month | `"15"` | | `current_month` | string | Month number (1-12) | `"1"` | | `current_year` | string | Four-digit year | `"2026"` | | `current_weekday` | string | Full weekday name | `"Wednesday"` | ## Call Variables | Variable | Type | Description | Example Value | | ----------------- | ------ | ------------------------------- | --------------------------- | | `call_id` | string | Unique identifier for this call | `"call_a1b2c3"` | | `call_type` | string | Type of call | `"voice"` | | `direction` | string | Call direction | `"inbound"` or `"outbound"` | | `call_start_time` | string | ISO timestamp when call began | `"2026-01-15T14:30:00Z"` | ## User Variables | Variable | Type | Description | Example Value | | ----------------------- | ------ | ---------------------------- | --------------------- | | `user_number` | string | User's phone number | `"+1 (555) 123-4567"` | | `user_number_area_code` | string | Area code from user's number | `"555"` | ## Agent Variables | Variable | Type | Description | Example Value | | -------------- | ------ | ------------------------- | --------------------- | | `agent_number` | string | Agent's phone number | `"+1 (555) 000-0000"` | | `agent_name` | string | Human-readable agent name | `"Customer Support"` | | `agent_id` | string | Unique agent identifier | `"agent_001"` | ## Usage Reference system variables with double curly braces: ``` "Good {{current_weekday}}! Your call started at {{call_start_time}}." "You're speaking with {{agent_name}}. Caller: {{user_number}}." ``` See [Template Syntax & Naming](./syntax-and-naming) for rules and [Availability & Context](./availability-and-context) for where system variables apply. # Troubleshooting Source: https://docs.tryhamsa.com/agents/variables/troubleshooting Common variable and tool-testing issues ## Common Issues ### Variable not showing in dropdown * **Cause:** Variable comes from a node that doesn’t run before the current node. * **Fix:** Check flow order; the variable must be created by a predecessor node (or be system/custom). ### "Variable not found" * **Cause:** Typo in name or variable was removed. * **Fix:** Check spelling and that the variable still exists in the right scope. ### JSONPath extraction returns null * **Cause:** Path doesn’t match the actual (or expected) response. * **Fix (API):** Run **Test Tool**, inspect response, use path selector on that response, check preview. Consider optional/missing fields. * **Fix (Web):** Ensure expected response matches real web tool output; test manually; use path selector on expected structure; check object vs string. ### Tool test fails or returns error * **Cause:** Bad config, auth, or API problem. * **Fix:** Check URL, method, headers, body; verify credentials; read error in test response; test the API directly (e.g. Postman). ### Path selector empty or wrong * **API:** Ensure **Test Tool** succeeded and response is 2xx and JSON (not HTML). * **Web:** Provide expected response; ensure it’s valid JSON if object; confirm format (object vs string). ### Works in test, fails in production * **Cause:** Production response shape differs from test. * **Fix:** Test with production-like data; handle optional/missing fields; add error handling; test success and error shapes. ### Can’t select path in path selector * **Cause:** Invalid or very complex response. * **Fix:** Validate JSON; simplify if possible; try manual JSONPath or extract a parent and use static variables to parse. ### AI extraction not working * **Cause:** Prompt too vague. * **Fix:** Make the extraction prompt specific and add examples. ### DTMF variable conflicts with transitions * **Cause:** DTMF capture on number keys while transitions use same keys. * **Fix:** Turn off number-key transitions or use different DTMF keys for capture vs transitions. ### Static variable shows wrong value * **Cause:** Referenced variables not available or have wrong values. * **Fix:** Check that referenced variables exist and are in scope; check defaults. ### Slow with many variables * **Cause:** Too many variables or heavy nested structures. * **Fix:** Remove unused variables; simplify structures. ### Variable not available in single prompt agent * **Cause:** Using extracted or static variables, which single prompt agents don’t support. * **Fix:** Single prompt agents support only **system** and **custom** variables. If you need extraction or flow logic, use a Flow Builder agent. ### Custom variable not showing in single prompt agent * **Cause:** Variable not defined in the Variables Panel. * **Fix:** Open the Variables Panel, add the custom variable with name and default value. It will be available as `{{variable_name}}` in the prompt and stored as `params` in the configuration. ### Single prompt agent needs to extract data * **Cause:** Single prompt agents don’t support variable extraction from conversations or tools. * **Fix:** Use a Flow Builder agent and conversation/tool nodes with AI or toolpath extraction. Single prompt agents are intended for simple Q\&A without extraction. ## Tool Testing **"Test Tool" disabled or not working:** Finish required fields (URL, method, auth). **Test slow or timeout:** Check endpoint and network; increase timeout if possible; try a simpler endpoint. **Test returns HTML instead of JSON:** Wrong URL or auth; verify endpoint and headers; test in browser/Postman. **Works in test, not in production:** Use realistic test data; handle null/optional fields; add error handling. **Web tool – unknown response format:** Run the web tool manually; inspect console/returned data; document format and use as expected response. **Web tool – different format than expected:** Update expected response; reconfigure extraction; re-test path selector; consider string vs object. **String vs object for web tool:** * **String:** One piece of data, simple text (e.g. `"Order #12345 confirmed"`). * **Object:** Multiple fields, structured data (e.g. `{"order_id": "12345", "status": "confirmed", "total": 99.99}`). **Path selector and string response:** For string responses use `$` (entire string). Don’t use nested paths on strings; use object format or extract full string and parse in static variables if needed. See [Extracted Variables](./extracted-variables), [Best Practices](./best-practices), and [Examples](./examples) for more context. # UI Components & Validation Source: https://docs.tryhamsa.com/agents/variables/ui-and-validation Variables panel, inputs, builders, and validation ## User Interface Components ### Variables Panel **Location**: Right sidebar in the flow builder **Shows:** * System variables (15+) * Custom variables * Summary count of extracted variables by node **Actions:** Add, edit, delete custom variables; view details and defaults. **Does not show:** Per-node extracted/static variables (those appear in node context and node config). ### Variable Input Components Used when editing text fields in the flow builder. **Shows:** Variables that are valid in the current context (system, custom, and for flow agents: extracted/static from predecessor nodes). **Features:** Context-aware list, search/filter, categories, type hints, click to insert `{{variable_name}}`. ### Variable Selection Modal **Features:** * Filtered by context (only variables available at the current node) * Suggestions by node type * Tabs by category (system, custom, extracted, static) * Search and preview * Validation of references ### Variable Builder (Extraction) Used in conversation and tool nodes to define extracted variables. **Features:** Add/edit/delete extracted variables, extraction prompts (AI), JSONPath (toolpath), data types, required flag, enums, nested objects/arrays. ### Static Variables Builder Used in nodes to define static variables. **Features:** Add/edit/delete static variables, all data types, template support, JSON editor for objects/arrays, validation, duplicate checks. ## Validation System ### Name Validation * **Format**: snake\_case * **Uniqueness**: No duplicate names in the same scope * **Reserved**: No system variable names * **Length**: 1–50 characters ### Reference Validation * **Existence**: Referenced variable exists * **Availability**: Variable is available at the current node * **Syntax**: Valid `{{variable_name}}` form * **Circular references**: Detected and reported ### Type Validation * **Data type**: Value matches declared type * **Enum**: Value is one of the allowed options when enum is used * **Required**: Required variables must have values ### Extraction Validation * **AI**: Extraction prompt present * **Toolpath**: Valid JSONPath * **DTMF**: No conflicting DTMF transitions Validation runs in the background, updates as you edit, and suggests fixes where possible. ## Performance * **Node availability cache**: Cached per node; invalidated on flow or variable changes * **Lookups**: Map-based (e.g. name → variable, node → available variables) * **Batching**: Recalculation and validation are batched * **Flow–variables bridge**: Keeps flow and variable stores in sync without circular dependencies See [Advanced Features](./advanced) for technical details and [Troubleshooting](./troubleshooting) for common validation issues. # Configuring Webhooks in Dashboard Source: https://docs.tryhamsa.com/agents/webhooks/introduction Set up webhook endpoints for your AI agents using the Hamsa dashboard # Configuring Webhooks Learn how to configure webhook endpoints for your AI agents to receive real-time call events and conversation data. ## What are Webhooks? Webhooks allow your applications to receive real-time notifications about call events, transcriptions, and conversation outcomes. When a voice call completes or specific events occur, Hamsa sends HTTP POST requests to your configured endpoint with relevant data. Instant notifications as calls progress, from start to completion Full transcripts, recordings, and extracted information Pass ANY custom data that gets echoed back for identification HTTPS-only with Bearer token authentication support ## Prerequisites Before setting up webhooks, ensure you have: Your webhook endpoint must be reachable from the internet. Use ngrok for local development. All webhook URLs must use HTTPS. HTTP endpoints will be rejected. Express.js, Flask, FastAPI, or any framework that can handle POST requests. Prepare to implement Bearer token authentication (recommended for production). ## Webhook URL Requirements **HTTPS Required:** * All webhook URLs must use HTTPS protocol * HTTP endpoints will be rejected * Self-signed certificates are not supported * Certificate must be valid and not expired **Valid Examples:** ``` ✅ https://api.yourcompany.com/webhook/hamsa ✅ https://webhook.example.com/hamsa/events ✅ https://your-app.herokuapp.com/webhooks/calls ❌ http://api.yourcompany.com/webhook (HTTP not allowed) ❌ https://192.168.1.100/webhook (local IPs not accessible) ❌ https://localhost:3000/webhook (localhost not accessible) ``` ### Local Development Setup For local development, use ngrok to expose your localhost: ```bash theme={null} # Install ngrok npm install -g ngrok # or brew install ngrok # Start your local server node server.js # Runs on port 3000 # In another terminal, start ngrok ngrok http 3000 # Use the ngrok HTTPS URL in your webhook configuration # Example: https://abc123.ngrok.io/webhook ``` ## Authentication Options ### Option 1: No Authentication (Development Only) Use for development or testing: ```json theme={null} { "webhookUrl": "https://abc123.ngrok.io/webhook", "webhookAuth": { "authKey": "noAuth" } } ``` Not recommended for production. Anyone who discovers your webhook URL can send requests to it. ### Option 2: Bearer Token Authentication (Recommended) Use for production environments: ```json theme={null} { "webhookUrl": "https://api.yourcompany.com/webhook", "webhookAuth": { "authKey": "bearer", "authSecret": "Bearer your_secret_token_here" } } ``` **Token Format Requirements:** * Must include the word "Bearer" followed by your token * Example: `Bearer sk_live_abc123xyz789` * Token should be long and randomly generated * Never commit tokens to source control **Generating Secure Tokens:** ```bash theme={null} # Generate a random token (Linux/Mac) openssl rand -base64 32 # Or use Node.js node -e "console.log(require('crypto').randomBytes(32).toString('base64'))" # Or use Python python -c "import secrets; print(secrets.token_urlsafe(32))" ``` ## Adding Webhook to Your Agent Go to your agent's configuration page in the Hamsa dashboard Scroll to the **Call Webhook** section and click to expand Input your publicly accessible HTTPS webhook URL Choose authentication method and enter your Bearer token if applicable Save your agent configuration to activate the webhook Webhooks are configured per agent. Each agent can have its own webhook URL and authentication settings. ## Event Types Your webhook receives various events throughout a call's lifecycle: | Event | When It Fires | Contains | | ------------------------ | ----------------- | ---------------------------------------- | | **call.started** | Call begins | Caller info, timestamp, custom params | | **call.answered** | Call connected | Connection details, ring duration | | **transcription.update** | User/agent speaks | Real-time text, speaker identification | | **tool.executed** | Agent uses a tool | Tool name, input, output, duration | | **call.ended** | Call completes | Full transcript, recording, outcome data | ## Testing Your Webhook ### Test with cURL ```bash theme={null} # Test basic connectivity curl -X POST https://your-endpoint.com/webhook \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your_secret_token" \ -d '{"test": true}' # Should return 200 OK ``` ### Test from Dashboard 1. Configure your webhook URL and authentication 2. Save your agent configuration 3. Make a test call to your agent 4. Monitor your webhook endpoint for incoming events 5. Verify you receive the `call.ended` event with full data ## Common Issues ### Webhook Not Receiving Data **Possible Causes:** * Webhook URL is not publicly accessible * Webhook URL not configured in Hamsa dashboard * Firewall/security rules blocking POST requests * Server not running or crashed * HTTPS certificate invalid **Solutions:** ```bash theme={null} # Test your webhook endpoint curl -X POST https://your-endpoint.com/webhook \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your_token" \ -d '{"test": true}' # Should return 200 OK ``` ### Authentication Failures **Possible Causes:** * Bearer token mismatch * Token format incorrect (missing "Bearer" prefix) * Token changed in dashboard but not in code **Solution:** * Verify token format: `Bearer sk_live_abc123xyz789` * Ensure token matches exactly between dashboard and your code * Check for extra spaces or formatting issues ## Next Steps Now that you've configured webhooks in the dashboard, learn how to implement webhook handlers: Complete guide to implementing webhook endpoints and processing events Learn about webhook concepts and patterns Configure what data your agent extracts Test your webhook integration # Create a new web tool. Source: https://docs.tryhamsa.com/api-reference/create-a-new-web-tool /api-reference/openapi.json post /v1/voice-agents/web-tool # Create new knowledge base items. Source: https://docs.tryhamsa.com/api-reference/create-new-knowledge-base-items /api-reference/openapi.json post /v1/voice-agents/knowledge-base # Create TTS history Source: https://docs.tryhamsa.com/api-reference/create-tts-history /api-reference/openapi.json post /v2/tts/histories Create a new TTS history entry for a generated audio clip. # Create TTS voice Source: https://docs.tryhamsa.com/api-reference/create-tts-voice /api-reference/openapi.json post /v2/tts/voices Create a new TTS voice under the current project. # Delete a web tool by Id. Source: https://docs.tryhamsa.com/api-reference/delete-a-web-tool-by-id /api-reference/openapi.json delete /v1/voice-agents/web-tool/{id} # Delete TTS history Source: https://docs.tryhamsa.com/api-reference/delete-tts-history /api-reference/openapi.json delete /v2/tts/histories/{id} Delete a TTS history entry by ID. # Delete TTS voice Source: https://docs.tryhamsa.com/api-reference/delete-tts-voice /api-reference/openapi.json delete /v2/tts/voices/{id} Delete an existing TTS voice. # Add Phone Number to a User Route Source: https://docs.tryhamsa.com/api-reference/endpoint/add-phone-number /api-reference/openapi.json post /v1/voice-agents/phone-number # Add URL to Knowledge Base Item Source: https://docs.tryhamsa.com/api-reference/endpoint/add-url-to-kb-item /api-reference/openapi.json post /v1/voice-agents/knowledge-base/{id}/url Adds a new URL to an existing knowledge base URL item for processing. # Get AI Content Cost Estimate Route Source: https://docs.tryhamsa.com/api-reference/endpoint/ai-content-estimate /api-reference/openapi.json get /v1/jobs/ai-content/estimate Returns the estimated cost for the specified AI content job. # Assign Phone Number to a Voice Agent Route Source: https://docs.tryhamsa.com/api-reference/endpoint/assign-phone-number /api-reference/openapi.json post /v1/voice-agents/assign-number # Create an Outbound Call Source: https://docs.tryhamsa.com/api-reference/endpoint/call-phone-number /api-reference/openapi.json post /v1/voice-agents/phone-number/call # Cancel Campaign Source: https://docs.tryhamsa.com/api-reference/endpoint/cancel-campaign /api-reference/openapi.json post /v1/voice-agents/campaigns/{id}/cancel Cancels a running or scheduled campaign. Once cancelled, the campaign cannot be restarted. # Clone Voice Agent Route Source: https://docs.tryhamsa.com/api-reference/endpoint/clone-voice-agent /api-reference/openapi.json post /v1/voice-agents/clone Use this route to clone an existing agent. You can use it to clone one of the voice agents templates created by our experts! # Create Campaign Source: https://docs.tryhamsa.com/api-reference/endpoint/create-campaign /api-reference/openapi.json post /v1/voice-agents/campaigns Creates a new outbound campaign with specified recipients, voice agent, and scheduling configuration. # Create Collection Source: https://docs.tryhamsa.com/api-reference/endpoint/create-collection /api-reference/openapi.json post /v1/voice-agents/collections Creates a new collection for organizing web tools. # Create Speech to Text Source: https://docs.tryhamsa.com/api-reference/endpoint/create-job-v2 /api-reference/openapi.json post /v2/jobs Create a transcription job. # Create Secret Source: https://docs.tryhamsa.com/api-reference/endpoint/create-secret /api-reference/openapi.json post /v1/projects/secrets Creates a new secret for the specified project. Secrets are encrypted and stored securely. # Create Voice Agent Route Source: https://docs.tryhamsa.com/api-reference/endpoint/create-voice-agent /api-reference/openapi.json post /v1/voice-agents Create a new voice agent to start using our powerful and robust voice assistant feature. This route requires an API key for authentication. # Create Voice Agent Source: https://docs.tryhamsa.com/api-reference/endpoint/create-voice-agent-v2 /api-reference/openapi.json post /v2/voice-agents Creates a new voice agent using the V2 API with enhanced configuration options. # Create Voice Dictionary Source: https://docs.tryhamsa.com/api-reference/endpoint/create-voice-dictionary /api-reference/openapi.json post /v1/voice-agents/voice-dictionaries Creates a new voice dictionary with custom pronunciation rules. # Create Customized AI Content Route Source: https://docs.tryhamsa.com/api-reference/endpoint/custom-ai-content /api-reference/openapi.json post /v1/jobs/ai-content/custom Generates AI content based on the specified transcription job ID and parameters. # Delete Campaign Source: https://docs.tryhamsa.com/api-reference/endpoint/delete-campaign /api-reference/openapi.json delete /v1/voice-agents/campaigns/{id} Soft deletes a campaign by ID. The campaign will be marked as deleted but not permanently removed from the database. # Delete Collection Source: https://docs.tryhamsa.com/api-reference/endpoint/delete-collection /api-reference/openapi.json delete /v1/voice-agents/collections/{id} Deletes an existing collection. Web tools in the collection will be moved outside the collection. # Delete Job Source: https://docs.tryhamsa.com/api-reference/endpoint/delete-job-v2 /api-reference/openapi.json delete /v2/jobs/{id} Delete a job by its unique identifier. # Delete Knowledge Base Item Source: https://docs.tryhamsa.com/api-reference/endpoint/delete-kb-item /api-reference/openapi.json delete /v1/voice-agents/knowledge-base/{id} Deletes a knowledge base item. Returns an error if the item is currently active in a voice agent. # Delete Phone Number Source: https://docs.tryhamsa.com/api-reference/endpoint/delete-phone-number /api-reference/openapi.json delete /v1/voice-agents/phone-number Removes a phone number from the user's account. # Delete Secret Source: https://docs.tryhamsa.com/api-reference/endpoint/delete-secret /api-reference/openapi.json delete /v1/projects/secrets/{id} Permanently deletes a secret from the project. # Delete URL from Knowledge Base Item Source: https://docs.tryhamsa.com/api-reference/endpoint/delete-url-from-kb-item /api-reference/openapi.json delete /v1/voice-agents/knowledge-base/{id}/url Removes a specific URL from an existing knowledge base URL item. # Export Conversations Source: https://docs.tryhamsa.com/api-reference/endpoint/export-conversations /api-reference/openapi.json get /v1/agent-analytics/conversations/export Exports conversation data for a voice agent as an Excel file. Returns the file as a downloadable attachment. # Generate AI Content Source: https://docs.tryhamsa.com/api-reference/endpoint/generate-transcription-ai-content-v2 /api-reference/openapi.json post /v2/jobs/generate-transcription-ai-content Submit a transcription job that also generates AI content based on provided parts. # Generate Text to Speech Route Source: https://docs.tryhamsa.com/api-reference/endpoint/generate-tts /api-reference/openapi.json post /v1/jobs/text-to-speech # Get AI Content Route Source: https://docs.tryhamsa.com/api-reference/endpoint/get-ai-content /api-reference/openapi.json get /v1/jobs/ai-content # Get Voice Agents List Route Source: https://docs.tryhamsa.com/api-reference/endpoint/get-all-voice-agents /api-reference/openapi.json get /v1/voice-agents # Get Call Log by ID Source: https://docs.tryhamsa.com/api-reference/endpoint/get-call-log /api-reference/openapi.json get /v1/agent-analytics/logs/{id} Retrieves a single call log record by its unique identifier. # Get Campaign by ID Source: https://docs.tryhamsa.com/api-reference/endpoint/get-campaign /api-reference/openapi.json get /v1/voice-agents/campaigns/{id} Retrieves a specific campaign by ID with recipients grouped by status (pending, queued, in-progress, completed, failed, no-answer). # Get Conversation by ID Source: https://docs.tryhamsa.com/api-reference/endpoint/get-conversation /api-reference/openapi.json get /v1/voice-agents/conversation/{conversationId} Retrieves detailed information about a specific conversation including call logs, performance metrics, and associated voice agent configuration. # Get Job Details By Id Source: https://docs.tryhamsa.com/api-reference/endpoint/get-job-by-id /api-reference/openapi.json get /v1/jobs # Get Single Job Source: https://docs.tryhamsa.com/api-reference/endpoint/get-job-v2 /api-reference/openapi.json get /v2/jobs/view/{id} Retrieve detailed information about a specific job. # Get Jobs List Source: https://docs.tryhamsa.com/api-reference/endpoint/get-jobs-list /api-reference/openapi.json post /v1/jobs/all # Get Knowledge Base Item by ID Source: https://docs.tryhamsa.com/api-reference/endpoint/get-kb-item /api-reference/openapi.json get /v1/voice-agents/knowledge-base/{id} Retrieves detailed information about a specific knowledge base item. # Get Knowledge Base Size Info Source: https://docs.tryhamsa.com/api-reference/endpoint/get-kb-size-info /api-reference/openapi.json get /v1/voice-agents/knowledge-base/size-info Retrieves the total size of all knowledge base items and the size limit based on the subscription plan. # Get Overview Analytics Source: https://docs.tryhamsa.com/api-reference/endpoint/get-overview-analytics /api-reference/openapi.json get /v1/agent-analytics/overview Retrieves overview analytics for voice agents including live sessions, total sessions, average session duration, and calls over time. # Get Performance Analytics Source: https://docs.tryhamsa.com/api-reference/endpoint/get-performance-analytics /api-reference/openapi.json get /v1/agent-analytics/performance Retrieves performance analytics for voice agents including ASR processing time, LLM response time, TTS generation time, latency, and error rates. # Get Phone Number by its ID Route Source: https://docs.tryhamsa.com/api-reference/endpoint/get-phone-number /api-reference/openapi.json get /v1/voice-agents/phone-number # Get Project By API Key Source: https://docs.tryhamsa.com/api-reference/endpoint/get-project-by-api-key /api-reference/openapi.json get /v1/projects/by-api-key # Get Satisfaction and Outcome Analytics Source: https://docs.tryhamsa.com/api-reference/endpoint/get-satisfaction-analytics /api-reference/openapi.json get /v1/agent-analytics/satisfaction Retrieves satisfaction and outcome analytics for voice agents including NPS score, sentiment distribution, CSAT score, first call resolution, and escalation rate. # Get A Voice Agent By Id Route Source: https://docs.tryhamsa.com/api-reference/endpoint/get-voice-agent-by-id /api-reference/openapi.json get /v1/voice-agents/{voiceAgentId} # Get Voice Agent Source: https://docs.tryhamsa.com/api-reference/endpoint/get-voice-agent-v2 /api-reference/openapi.json get /v2/voice-agents/{voiceAgentId} Retrieves a specific voice agent by its unique identifier. # Get Voice Dictionary by ID Source: https://docs.tryhamsa.com/api-reference/endpoint/get-voice-dictionary /api-reference/openapi.json get /v1/voice-agents/voice-dictionaries/{id} Retrieves a specific voice dictionary by its unique identifier. # List Call Logs Source: https://docs.tryhamsa.com/api-reference/endpoint/list-call-logs /api-reference/openapi.json get /v1/agent-analytics/logs Retrieves a list of call logs for a specific job. # List Campaigns Source: https://docs.tryhamsa.com/api-reference/endpoint/list-campaigns /api-reference/openapi.json get /v1/voice-agents/campaigns Retrieves a paginated list of campaigns with optional filtering by voice agent and search query. # List Collections Source: https://docs.tryhamsa.com/api-reference/endpoint/list-collections /api-reference/openapi.json get /v1/voice-agents/collections/list Retrieves a paginated list of collections with optional search functionality. # List Jobs Source: https://docs.tryhamsa.com/api-reference/endpoint/list-jobs-v2 /api-reference/openapi.json get /v2/jobs Retrieve a paginated list of jobs with optional filtering and sorting. # List Call Records (Minimal) Source: https://docs.tryhamsa.com/api-reference/endpoint/list-minimal-calls /api-reference/openapi.json get /v1/voice-agents/conversations/minimal-list Returns a paginated, lightweight list of voice-agent call records for a project. Each row carries only the fields needed for dashboard timelines (id, createdAt, status, agent, duration, channel, phone numbers). Filter by voice agent, one-or-many statuses, and a UTC time range on `createdAt`. Timestamps are **UTC epoch milliseconds**. Convert the user's local window to UTC on the client before calling. # List User Phone Numbers Route Source: https://docs.tryhamsa.com/api-reference/endpoint/list-phone-numbers /api-reference/openapi.json get /v1/voice-agents/phone-number/list # List Secrets Source: https://docs.tryhamsa.com/api-reference/endpoint/list-secrets /api-reference/openapi.json get /v1/projects/secrets/list Retrieves a paginated list of secrets for the specified project. Secret values are not included in the response. # List Voice Agents Source: https://docs.tryhamsa.com/api-reference/endpoint/list-voice-agents-v2 /api-reference/openapi.json get /v2/voice-agents Retrieves a paginated list of voice agents with filtering and sorting options. # List Voice Dictionaries Source: https://docs.tryhamsa.com/api-reference/endpoint/list-voice-dictionaries /api-reference/openapi.json get /v1/voice-agents/voice-dictionaries/list Retrieves a paginated list of voice dictionaries. # Move Web Tool to Collection Source: https://docs.tryhamsa.com/api-reference/endpoint/move-tool-to-collection /api-reference/openapi.json post /v1/voice-agents/collections/move Moves a web tool into a collection or removes it from a collection (when collectionId is null). # Pause Campaign Source: https://docs.tryhamsa.com/api-reference/endpoint/pause-campaign /api-reference/openapi.json post /v1/voice-agents/campaigns/{id}/pause Pauses a running or scheduled campaign. Paused campaigns can be resumed later. # Create AI Content Route Source: https://docs.tryhamsa.com/api-reference/endpoint/post-ai-content /api-reference/openapi.json post /v1/jobs/ai-content # Preload Cloned TTS Voice Source: https://docs.tryhamsa.com/api-reference/endpoint/preload-cloned-tts-voice /api-reference/openapi.json post /v2/tts/voices/custom/preload This endpoint allows you to preload a custom cloned voice into the system's before using it. You only need to preload the voice only once. You may preload it once your application starts to reduce any latency if you use the Real-Time APIs. # Resume Campaign Source: https://docs.tryhamsa.com/api-reference/endpoint/resume-campaign /api-reference/openapi.json post /v1/voice-agents/campaigns/{id}/resume Resumes a previously paused campaign. # Retry Campaign Source: https://docs.tryhamsa.com/api-reference/endpoint/retry-campaign /api-reference/openapi.json post /v1/voice-agents/campaigns/{id}/retry Retries failed or no-answer recipients in a campaign. Only recipients with FAILED or NO_ANSWER status will be retried. # Generate Speech to Text Transcription Source: https://docs.tryhamsa.com/api-reference/endpoint/rt-generate-stt /api-reference/openapi.json post /v1/realtime/stt # Generate Text to Speech File Data Source: https://docs.tryhamsa.com/api-reference/endpoint/rt-generate-tts /api-reference/openapi.json post /v1/realtime/tts # Generate Streamed Text to Speech File Data Source: https://docs.tryhamsa.com/api-reference/endpoint/rt-generate-tts-stream /api-reference/openapi.json post /v1/realtime/tts-stream From the user's perspective, this is a standard request. In the response, we include specific headers: 'Transfer-Encoding' is set to 'chunked' to enable streaming, 'Connection' is set to 'keep-alive' to maintain the connection, and 'Content-Type' is set to 'audio/wav' to indicate the media type. These headers allow the client to stream audio data from the server in real time. Important Note: after collecting the chunks, you need to add the wav header manually to the data. If you wish to get a wav header, please use the [Generate TTS File Data API](/api-reference/endpoint/rt-generate-tts). # Start a Call for a Conversation Route Source: https://docs.tryhamsa.com/api-reference/endpoint/start-a-call /api-reference/openapi.json post /v1/voice-agents/call # Get Usage Statistics Chart Source: https://docs.tryhamsa.com/api-reference/endpoint/statistics-chart /api-reference/openapi.json get /v1/projects/statistics/chart # Get Usage Statistics Numbers Source: https://docs.tryhamsa.com/api-reference/endpoint/statistics-numbers /api-reference/openapi.json get /v1/projects/statistics/numbers # Terminate Conversation Source: https://docs.tryhamsa.com/api-reference/endpoint/terminate-conversation /api-reference/openapi.json get /v1/voice-agents/conversation/{conversationId}/terminate Terminates an active or pending conversation and closes the associated LiveKit room. # Test API Tool Configuration Source: https://docs.tryhamsa.com/api-reference/endpoint/test-api-tool /api-reference/openapi.json post /v1/voice-agents/web-tool/test-api-tool Validates API connectivity with retry logic and streams real-time test results via Server-Sent Events. # Toggle Voice Dictionary Activation Source: https://docs.tryhamsa.com/api-reference/endpoint/toggle-voice-dictionary-activation /api-reference/openapi.json post /v1/voice-agents/voice-dictionaries/toggle-activation Activates or deactivates a voice dictionary for a specific voice agent. # Transcribe Route Source: https://docs.tryhamsa.com/api-reference/endpoint/transcribe /api-reference/openapi.json post /v1/jobs/transcribe # Unassign Phone Number to a Voice Agent Route Source: https://docs.tryhamsa.com/api-reference/endpoint/unassign-phone-number /api-reference/openapi.json post /v1/voice-agents/unassign # Update Campaign Name Source: https://docs.tryhamsa.com/api-reference/endpoint/update-campaign /api-reference/openapi.json patch /v1/voice-agents/campaigns/{id} Updates the name of an existing campaign by ID. # Update Collection Source: https://docs.tryhamsa.com/api-reference/endpoint/update-collection /api-reference/openapi.json patch /v1/voice-agents/collections/{id} Updates an existing collection's name or description. # Update Job Title Source: https://docs.tryhamsa.com/api-reference/endpoint/update-job-title-v2 /api-reference/openapi.json patch /v2/jobs/{id} Update the title of a job. # Update Secret Source: https://docs.tryhamsa.com/api-reference/endpoint/update-secret /api-reference/openapi.json patch /v1/projects/secrets/{id} Updates an existing secret. You can update the name, value, description, or tags. # Update Voice Agent Route Source: https://docs.tryhamsa.com/api-reference/endpoint/update-voice-agent /api-reference/openapi.json patch /v1/voice-agents/{voiceAgentId} # Update Voice Agent Source: https://docs.tryhamsa.com/api-reference/endpoint/update-voice-agent-v2 /api-reference/openapi.json patch /v2/voice-agents/{voiceAgentId} Updates an existing voice agent with new configuration. # Update Voice Dictionary Source: https://docs.tryhamsa.com/api-reference/endpoint/update-voice-dictionary /api-reference/openapi.json patch /v1/voice-agents/voice-dictionaries/{id} Updates an existing voice dictionary. # Create Web Tool Source: https://docs.tryhamsa.com/api-reference/endpoint/v2/create-web-tool /api-reference/openapi.json post /v2/voice-agents/web-tool Creates a new web tool for a project. Web tools can be of type FUNCTION, MCP, or WEB_TOOL. # List Web Tools Source: https://docs.tryhamsa.com/api-reference/endpoint/v2/list-web-tools /api-reference/openapi.json get /v2/voice-agents/web-tool/list Retrieves a paginated list of web tools with optional filtering by project, status, type, collection, and search term. # Update Web Tool Source: https://docs.tryhamsa.com/api-reference/endpoint/v2/update-web-tool /api-reference/openapi.json patch /v2/voice-agents/web-tool/{id} Updates an existing web tool by ID. All fields are optional except projectId. # Check Newer Versions Source: https://docs.tryhamsa.com/api-reference/endpoint/v2/version-check-web-tools /api-reference/openapi.json post /v2/voice-agents/web-tool/version-check Checks if newer versions are available for the specified web tools. Can also detect conflicts with user overrides. # Check Web Tool Version Updates Source: https://docs.tryhamsa.com/api-reference/endpoint/version-check /api-reference/openapi.json post /v1/voice-agents/web-tool/version-check Checks if there are newer versions available for the specified web tools. # Extract transcription from voice audio Source: https://docs.tryhamsa.com/api-reference/extract-transcription-from-voice-audio /api-reference/openapi.json post /v2/tts/voices/extract-transcription Extract a text transcription from a voice audio sample. # Favorite a TTS voice Source: https://docs.tryhamsa.com/api-reference/favorite-a-tts-voice /api-reference/openapi.json post /v2/tts/voices/{id}/favourite Mark or unmark a TTS voice as Favorite. # Get a web tool by ID. Source: https://docs.tryhamsa.com/api-reference/get-a-web-tool-by-id /api-reference/openapi.json get /v1/voice-agents/web-tool/{id} # Get default TTS voice Source: https://docs.tryhamsa.com/api-reference/get-default-tts-voice /api-reference/openapi.json get /v2/tts/voices/default/current Retrieve the default TTS voice for the current language. # Get TTS history Source: https://docs.tryhamsa.com/api-reference/get-tts-history /api-reference/openapi.json get /v2/tts/histories/{id} Retrieve a single TTS history entry by ID. # Get TTS voice Source: https://docs.tryhamsa.com/api-reference/get-tts-voice /api-reference/openapi.json get /v2/tts/voices/{id} Retrieve a single TTS voice by ID. # Introduction Source: https://docs.tryhamsa.com/api-reference/introduction API documentation for the Hamsa API This section contains the API reference documentation for the Hamsa API. ## Authentication The Hamsa API uses **API Key token authentication**. Include your API key in the `Authorization` header of every request: ``` Authorization: Token ``` You can create an API key from the dashboard. See [Create API Keys](/overview/create-api-keys) for details. ## Project ID Some endpoints require a **Project ID** to identify which project the request applies to. See [Finding Your Project ID](/overview/projects/overview#finding-your-project-id) for how to retrieve it. # List dialects Source: https://docs.tryhamsa.com/api-reference/list-dialects /api-reference/openapi.json get /v2/tts/dialects Retrieve available dialects for TTS voices. # List TTS histories Source: https://docs.tryhamsa.com/api-reference/list-tts-histories /api-reference/openapi.json get /v2/tts/histories List TTS history entries with pagination. # List TTS voices Source: https://docs.tryhamsa.com/api-reference/list-tts-voices /api-reference/openapi.json get /v2/tts/voices Retrieve available TTS voices with optional filtering, pagination, and source flags. # Preview TTS voice Source: https://docs.tryhamsa.com/api-reference/preview-tts-voice /api-reference/openapi.json post /v2/tts/voices/preview Generate a short preview clip for a TTS voice. # Return a list of Knowledge Base Items. Source: https://docs.tryhamsa.com/api-reference/return-a-list-of-knowledge-base-items /api-reference/openapi.json get /v1/voice-agents/knowledge-base/list # Return a list of Web Tools. Source: https://docs.tryhamsa.com/api-reference/return-a-list-of-web-tools /api-reference/openapi.json get /v1/voice-agents/web-tool/list # Toggle activation of a knowledge base item for a voice agent. Source: https://docs.tryhamsa.com/api-reference/toggle-activation-of-a-knowledge-base-item-for-a-voice-agent /api-reference/openapi.json post /v1/voice-agents/knowledge-base/toggle-activation # Toggle activation of a web tool for a voice agent. Source: https://docs.tryhamsa.com/api-reference/toggle-activation-of-a-web-tool-for-a-voice-agent /api-reference/openapi.json post /v1/voice-agents/web-tool/toggle-activation # Update a knowledge base item by Id. Source: https://docs.tryhamsa.com/api-reference/update-a-knowledge-base-item-by-id /api-reference/openapi.json patch /v1/voice-agents/knowledge-base/{id} # Update a web tool by Id. Source: https://docs.tryhamsa.com/api-reference/update-a-web-tool-by-id /api-reference/openapi.json patch /v1/voice-agents/web-tool/{id} # Changelog Source: https://docs.tryhamsa.com/changelog/main What is new in Hamsa ## Agents platform #### Chat Agent A new Chat channel has been introduced, allowing users to interact with AI agents through text conversations in addition to Telephony and Web. * **New Chat Channel:** Chat is now available as a dedicated communication channel alongside Telephony and Web. * **Chat History:** Chat sessions are now available in Call History with a dedicated channel filter. Completed chats display the full conversation transcript, while active chats can be monitored live * **SDK:** the Voice Agents SDK now supports text chat sessions, so you can build a chat interface for your agents in your own app. #### Agent Enhancements Improved agent configuration, variable handling, and workflow authoring experience. * **Jinja Support in Set Local Variables:** Added support for using **Jinja expressions** inside the **Set Local Variables** node, enabling more dynamic variable generation. * **Local Variable Preview in Router Node** : Added a preview of local variables configured within the **Router** node to improve visibility during flow creation. #### Knowledge Base Improvements Enhanced Knowledge Base management with improved processing controls and permissions. * **KB Processing Termination** : Users can now terminate the processing of Knowledge Base items directly from the platform. * **Permission Controls** :Added a new **Knowledge Base Cancel** permission in Project Settings to control which users can terminate Knowledge Base item processing. ## Agents platform #### Agent Publishing & Sharing Users can now deploy AI agents through public links or embed them directly into websites. * **Shareable Public Links:** Generate a public URL that can be shared with customers, partners, or website visitors, and End users can interact with the agent without requiring a Hamsa account. * **Website Embedding:** Embed agents into websites using a generated script, with simple setup with minimal configuration required. * **Customization options:** The published agent's appearance and behavior can be customized to match branding and preferred user experience. #### Improved Conversation Controls Enhanced interruption management and conversation flow handling to provide more control over agent interactions. * Added support for disabling interruptions during conversations. * Support New Transition Type **"After User Replied"** * Added a new transition type that automatically moves the conversation to the next node when the user provides any response. When this transition is enabled, all other transitions configured on the node are ignored, ensuring the conversation proceeds directly to the designated next node after the user replies. * Added support for per-transition variable extraction controls, enabling extraction behavior to be configured independently for each transition #### Stability & Quality Improvements * Implemented various bug fixes and platform improvements to enhance reliability, usability, performance, and overall user experience across the platform. ## Media platform #### Automated Video Creation from Voice Jobs The Video Generation feature enables users to automatically transform completed voice generation jobs into professional, shareable videos. Using the generated audio and script, the platform creates visual scenes, synchronizes them with the narration, and produces a ready-to-use video without requiring manual editing. #### Customization Options * Visual Styles: Realistic, Cartoon, Infographic * Aspect Ratios: Portrait (9:16), Landscape (16:9) * Captions: Enable or disable captions * Caption Styles: Word-by-Word, Build-Up, Full Sentence * Scene Transitions: None, Fade, Dissolve, Slide Left, Slide Right, Circle Open * Motion Effects: Optional Ken Burns effect #### Generation Process * Analyze the script * Generate visuals * Synchronize visuals with the voice-over * Generate and time captions when enabled * Assemble the final video #### Output & Delivery * MP4 video output * Generation progress tracking * Video preview before download * Downloadable final result ### Flows & Agent Behavior Improvements to how agents handle conversations, transitions, and live changes mid-call. * **Enhanced Turn Taking**: Introduced an improved turn-taking pipeline to enhance conversation flow and speech stability during agent interactions. * improved handling of numbers and long digit sequences * Smarter interruption detection * Reduced unwanted interruptions during agent speech * Legacy behavior preserved when disabled for backward compatibility * **Change Agent Settings Node**: Introduced a new node type that enables dynamic updates to agent system settings during active calls. * Supports updates for system instructions, voice and dialect * Supports updates for VAD settings, and response delay * Supports updates for interruption behavior ,and timeouts * Voice switching has also been hardened for safer runtime voice and dialect transition * **Improved Agent Transfers:** Transfer agent behavior now supports variable inheritance between agents and conversation history transfer. ### Speech & Prompting New STT model and finer-grained control over prompt enhancement. * **New STT Model**: Introduced support for the new Hamsa-STT-S3-beta model. Available models are now: * Hamsa-STT-S2 * Hamsa-STT-English * Hamsa-STT-S3-beta * **Prompt Enhancer Modes**: introduced a new Prompt Enhancer selector with three enhancement modes. * Disabled :No enhancements applied * Basic :Stable, model-agnostic prompts for predictable behavior * Advanced :Model-aware prompts with stronger guardrails, dynamic flow guidance, and live active-node context updates * **New Gemini Models** Added support for: * `Gemini-3.1-flash-lite` * `Gemini-3-flash-preview`. ### Observability & Webhooks More context in outcomes, webhooks, and logs to make debugging easier. * **Outcome Generation**: Outcomes now use the agent's configured OpenAI model and include enhanced agent context, extracted call variables, and caller context for higher-quality, more consistent analysis. * **Failure Webhooks**: `NO_ANSWER` and `FAILED`webhook payloads now include `conversationId`. * **Per-Node Logging**: Conversation logs now include `nodeId` for better debugging and traceability across multi-node flows. * **LLM Metadata in Call History**: Call history now records the LLM provider and model used for each call. ### Platform Improvements & Fixes Security, tooling, and stability fixes across the platform. * **Scoped API Keys**: API keys now support scoping with origin allowlists and scope assignment alongside root permissions. Expired keys are surfaced with an "expired" badge when listed. * **New JSON Editor:** The JSON editor has been replaced with a new version that auto-fixes common errors ### Media New creative capabilities for producing richer audio. * **Voice AI creations feature:** Generate complete voice overs from a natural-language description of what you need. * Provide a prompt, choose a dialect, and select the voice over type * Optionally enable background music generation * Each request returns three voice over suggestions * Suggestions are paired with matching voices and emotionally aligned background tracks when enabled * Generation runs asynchronously with Pending → Ready → Failed status tracking * Approve the preferred result once generation is complete * Failed generations are surfaced for easy retrying * **New Voices added:** Additional voices have been added to the library, expanding the options available for both voice over and TTS. ### Call Infrastructure & Performance Strengthening reliability, scalability, and accuracy of the calling experience. * **Concurrent Calls Stability:** Resolved outbound call concurrency issues, eliminating stuck `PENDING`calls and incorrect concurrency limits. * **Accurate Concurrency Enforcement**: Concurrency limits are now enforced correctly across all call types. * **Unified Concurrency Pool**: Campaign calls and direct API calls now share a single concurrency pool for consistent behavior. * **Improved Slot Handling:** Failed or unanswered calls now correctly release concurrency slots, preventing bottlenecks. * **Inbound Concurrency** **Enforcement**: Inbound calls now reserve slots in the user's call queue, ensuring limits are applied consistently. * **Inbound Credit Validation:** Inbound calls now validate account balance before connecting, preventing calls when credits are insufficient. ### Call Data & Exporting Improving data accessibility and resolving key limitations. * **Call Export Fix:** Resolved issues related to exporting call data, ensuring accurate and reliable downloads. * **Optimized Data Exporting**: Improved export performance by reducing memory usage, enabling reliable handling of large datasets without system instability. * **Scalable Data Processing**: Enhanced backend processing to support high-volume data operations efficiently and prevent application crashes. * **Sentiment Analysis Optimization**: Improved sentiment distribution processing to reduce memory consumption and produce faster, more reliable analytics. ### Analytics & Reporting Expanding visibility and enabling structured data extraction across environments. * **Dashboard Analytics Export:** Export functionality is now available from the Dashboard page across the Overview, Performance, and Satisfaction tabs. * **Structured Excel Report:** Exports produce a formatted Excel (`.xlsx`) file with three sheets: Overview, Performance, and Satisfaction. * **Report Metadata:** Each sheet includes a "Hamsa Analytics Report" header with the selected agent name/ID and export timestamp. * **Dynamic Filtering Support:** Exports respect active filters and date ranges, with filenames reflecting the selected period. ### Canvas & Flow Builder Improving usability, speed, and control when building and managing flows. * **Inline Node Renaming:** Nodes can now be renamed directly from the canvas with inline editing. * **Quick Node Picker**: Dropping an edge onto an empty area opens a modal to create and connect a node in one step. * **Auto Layout** : Automatically arranges nodes horizontally or vertically to keep flows clean and readable, with no overlap. * **Canvas Follow Toggle**: The canvas auto-pans to the active node during live calls, with a toggle to disable (saved per browser). * **Copy & Paste Nodes:** Nodes can now be copied and pasted directly within the canvas. ### APIs & Backend Enhancing system reliability and backend performance. * **Single Jobs API** **Fix:** Addressed bugs to improve stability and ensure consistent execution. ### Projects & Team Collaboration Enhancing how teams organize work and manage access across projects. * **Projects** : Organize work into dedicated projects, each with its own agents, phone numbers, knowledge bases, and call history. Easily switch between projects from the top navigation. * **Team Invitations** : Invite teammates via email through a streamlined signup flow. Expired invitations can be resent directly from the Members page. * **Roles & Permissions** * Assign roles * (Owner, Admin, User) and manage access with granular, per-resource permissions. Revert to role defaults at any time. * **Project Deactivation** * Owners can deactivate projects to prevent further changes. Deactivated projects are hidden from non-owners and can be reactivated at any time. * **Unsaved Changes Protection** * When switching projects with unsaved changes, you'll now be prompted to confirm, reducing the risk of accidental data loss. ### Call Settings More flexibility and control over your call experience. * **Extended Call Duration** * The maximum call duration has been increased from 30 minutes to 1 hour, and is now configured in minutes instead of seconds. * **Smart Call End Prompt** * Customize the prompt used by the Smart Call End feature to better detect natural conversation endings. ### Tools Enhancements to streamline workflows and improve testing. * **On-Hold Music** * Tools can now play on-hold music while a tool call is executing. * **Collection Filtering** * Filter the tools list by collection for faster navigation and improved organization. * **Tool Testing Improvements** * Disabled headers and parameters are now automatically excluded during testing for more accurate and reliable results. ### Call History Improved control over active calls. * **Terminate Active Calls** Active calls can now be terminated directly from both the call history table and the call details view. # Call Routing Guide Source: https://docs.tryhamsa.com/developers/agent-guides/call-routing Advanced routing patterns with router nodes, conditions, and intelligent call distribution ## Overview Call routing determines where conversations flow based on context, user input, and business logic. Effective routing ensures callers reach the right destination quickly, improving satisfaction and reducing handling time. **Routing Methods in Hamsa:** * **Router Nodes** - Conditional logic-based routing * **Transition Conditions** - Flow between nodes based on rules * **Natural Language** - AI-powered intent routing * **DTMF** - Keypad-based menu navigation * **Time-Based** - Route by time, day, or date * **Data-Driven** - Route based on caller data or API responses ## Routing Fundamentals ### Router Nodes Router nodes evaluate conditions and direct calls to appropriate destinations. **How Router Nodes Work:** 1. Evaluate conditions in order (top to bottom) 2. First matching condition wins 3. Route call to connected node 4. If no conditions match, use fallback (Always) **Basic Structure:** ```yaml theme={null} Router Node: Customer_Type_Router Conditions: - {{customer_tier}} == "platinum" → Platinum_Support - {{customer_tier}} == "gold" → Gold_Support - {{customer_tier}} == "silver" → Silver_Support - Always → Standard_Support ``` ### Transition Types Different ways to move between nodes: **1. Always Transition** * Unconditional, always fires * Used for sequential flow * No conditions needed **2. Natural Language Transition** * AI determines if condition met * Based on conversation context * Flexible, conversational **3. DTMF Transition** * Triggered by keypad press * Exact, predictable * Good for menus **4. Conditional Transition** * Based on variable values * Logical expressions * Data-driven routing ## Basic Routing Patterns ### Intent-Based Routing Route based on what the caller wants. ```yaml theme={null} Start Node: Message: "Thank you for calling. How can I help you today?" Extract Variables: - caller_intent: "Identify what the caller needs" ``` ```yaml theme={null} Router: Intent_Router Conditions: - {{caller_intent}} contains "sales" → Sales_Department - {{caller_intent}} contains "support" → Support_Department - {{caller_intent}} contains "billing" → Billing_Department - Always → General_Help ``` **Example Flow:** ``` Caller: "I want to buy your product" → Intent: "sales" → Routes to: Sales_Department Caller: "My account isn't working" → Intent: "support" → Routes to: Support_Department Caller: "I have a question about my bill" → Intent: "billing" → Routes to: Billing_Department ``` ### Priority-Based Routing Route urgent or VIP calls differently. ```yaml theme={null} Router: Priority_Router Conditions: # Emergency calls first - {{emergency_keyword}} == true → Emergency_Transfer # VIP customers second - {{customer_tier}} == "VIP" → VIP_Fast_Track # High-value issues third - {{issue_value}} > 10000 → Senior_Support # Everyone else - Always → Standard_Queue Emergency_Transfer: Type: Transfer Call Number: +1-800-EMERGENCY Message: "Transferring you immediately..." VIP_Fast_Track: Type: Conversation Message: "Welcome back, {{customer_name}}. A specialist will be with you in just a moment." Standard_Queue: Type: Conversation Message: "All representatives are currently assisting others. Please hold." ``` ### Skill-Based Routing Route to agents with specific skills. ```yaml theme={null} Router: Skill_Router Conditions: # Technical issues → Technical team - {{issue_type}} == "technical" AND {{product_category}} == "enterprise" → Enterprise_Tech_Support # Billing issues → Finance team - {{issue_type}} == "billing" OR {{issue_type}} == "refund" → Finance_Team # Product questions → Product specialists - {{issue_type}} == "product_info" → Product_Specialists # Account management → Account team - {{issue_type}} == "account" → Account_Management # Default - Always → General_Support ``` ## Advanced Routing Patterns ### Time-Based Routing Route differently based on time, day, or date. **Business Hours Routing:** ```yaml theme={null} Router: Hours_Router Conditions: # Weekend - {{current_weekday}} IN ["Saturday", "Sunday"] → Weekend_Message # Before business hours - {{current_time}} < "09:00" → After_Hours_Message # After business hours - {{current_time}} > "17:00" → After_Hours_Message # Lunch time (reduced staff) - {{current_time}} >= "12:00" AND {{current_time}} < "13:00" → Lunch_Queue # Business hours - Always → Business_Hours_Team Weekend_Message: Message: "Our offices are closed on weekends. Press 1 to leave a voicemail. Press 2 for emergency support, which may incur additional charges. Press 3 to hear our business hours." Transitions: - DTMF: 1 → Voicemail - DTMF: 2 → Emergency_Support - DTMF: 3 → Business_Hours_Info → Weekend_Message ``` **Holiday Routing:** ```yaml theme={null} Router: Holiday_Check Conditions: # Check if current date is a holiday - {{current_date}} == "2024-01-01" → Holiday_Message # New Year's - {{current_date}} == "2024-07-04" → Holiday_Message # July 4th - {{current_date}} == "2024-12-25" → Holiday_Message # Christmas # Normal day - Always → Hours_Router Holiday_Message: Message: "We're closed today for the holiday. Our offices will reopen on {{next_business_day}}. For emergencies, press 1 now." ``` **Timezone-Aware Routing:** ```yaml theme={null} Custom Variables: - caller_timezone: string Router: Timezone_Router Conditions: # East Coast hours (9 AM - 5 PM ET) - {{caller_timezone}} == "ET" AND {{current_time}} >= "09:00" AND {{current_time}} < "17:00" → East_Coast_Team # West Coast hours (9 AM - 5 PM PT) - {{caller_timezone}} == "PT" AND {{current_time}} >= "09:00" AND {{current_time}} < "17:00" → West_Coast_Team # After hours any timezone - Always → After_Hours_Support ``` ### Load-Based Routing Distribute calls based on queue length or agent availability. ```yaml theme={null} # This requires integration with your contact center system Router: Load_Balancer Conditions: # Check queue sizes via API - {{sales_queue_length}} < {{support_queue_length}} AND {{intent}} == "general" → Sales_Team # Route general inquiries to less busy team # Route to specific queues normally - {{intent}} == "sales" → Sales_Team - {{intent}} == "support" → Support_Team Tool: Check_Queue_Sizes Type: API Call URL: https://api.yourcontactcenter.com/queues Returns: - sales_queue_length - support_queue_length - average_wait_time ``` **Overflow Routing:** ```yaml theme={null} Router: Overflow_Check Conditions: # Primary team available - {{primary_queue_wait}} < 120 → # Less than 2 min wait Primary_Team # Overflow to backup team - {{primary_queue_wait}} >= 120 AND {{backup_team_available}} == true → Backup_Team # Offer callback - {{primary_queue_wait}} >= 300 → # 5+ min wait Callback_Offer Callback_Offer: Message: "All agents are busy. Current wait time is {{primary_queue_wait}} minutes. Press 1 to continue holding. Press 2 to request a callback." ``` ### Geographic Routing Route based on caller location. ```yaml theme={null} # Using area code Router: Geographic_Router Conditions: # East Coast (area codes) - {{user_number_area_code}} IN ["212", "718", "646", "917"] → NYC_Office - {{user_number_area_code}} IN ["617", "857"] → Boston_Office # West Coast - {{user_number_area_code}} IN ["415", "510", "650"] → SF_Office - {{user_number_area_code}} IN ["213", "310", "424"] → LA_Office # Default to nearest regional office - Always → Find_Nearest_Office # Using ZIP code (collected from caller) Router: ZIP_Router Conditions: - {{zip_code}} >= "10000" AND {{zip_code}} < "20000" → Northeast_Region - {{zip_code}} >= "90000" AND {{zip_code}} < "97000" → West_Coast_Region - Always → Central_Region ``` ### Language-Based Routing Route to language-specific agents. ```yaml theme={null} Language_Selection_Menu: Message: "For English, press 1. Para Español, oprima dos. Pour le Français, appuyez sur trois." Transitions: - DTMF: 1 → English_Router - DTMF: 2 → Spanish_Router - DTMF: 3 → French_Router English_Router: # Set language for this path Agent Language: en-US Voice: aura-asteria-en # Continue routing based on intent Conditions: - {{intent}} == "sales" → English_Sales - {{intent}} == "support" → English_Support Spanish_Router: Agent Language: es-MX Voice: aura-sofia-es Conditions: - {{intent}} == "sales" → Spanish_Sales - {{intent}} == "support" → Spanish_Support ``` ### Data-Driven Routing Route based on customer data from your systems. ```yaml theme={null} # Step 1: Identify caller Node: Identify_Caller Message: "Please enter your account number followed by pound." DTMF Input Capture: Variable: account_number Termination Key: # # Step 2: Lookup customer data Tool: Lookup_Customer URL: https://api.yourcrm.com/customers/{{account_number}} Returns: - customer_name - customer_tier - account_balance - last_purchase_date - assigned_agent # Step 3: Route based on data Router: Customer_Data_Router Conditions: # Negative balance → collections - {{account_balance}} < 0 → Collections_Team # Recently purchased → post-sales support - {{last_purchase_date}} within_days 30 → Post_Sales_Support # Has assigned agent → route to them - {{assigned_agent}} != null → Assigned_Agent # VIP tier → priority - {{customer_tier}} == "VIP" → VIP_Queue # Standard routing - Always → General_Support ``` ## Multi-Stage Routing ### Sequential Qualification Routing Progressively qualify and route callers. ```yaml theme={null} Stage 1: Initial Classification Message: "Are you a current customer or new customer?" Transitions: - Natural Language: "current customer" → Existing_Customer_Flow - Natural Language: "new customer" → New_Customer_Flow Stage 2a: Existing Customer Flow Message: "What can I help you with today?" Extract: issue_type Router: - {{issue_type}} == "problem" → Triage_Problem - {{issue_type}} == "question" → Answer_Question - {{issue_type}} == "upgrade" → Sales_Team Stage 2b: New Customer Flow Message: "Are you interested in our products or services?" Extract: interest_type Router: - {{interest_type}} == "products" → Product_Sales - {{interest_type}} == "services" → Service_Sales - {{interest_type}} == "both" → Full_Sales_Team Stage 3: Problem Triage (from Stage 2a) Message: "How urgent is this issue?" Extract: urgency Router: - {{urgency}} == "critical" → Priority_Support - {{urgency}} == "moderate" → Standard_Support - {{urgency}} == "low" → Self_Service_Options ``` ### Escalation Routing Route to higher tiers when needed. ```yaml theme={null} Level 1: Initial Support Type: Conversation Node Agent handles common issues Transitions: # Issue resolved - Natural Language: "problem solved" → Thank_And_Close # Needs escalation - Natural Language: "needs expert" OR {{attempt_count}} > 3 → Level_2_Router Level 2: Specialized Support Type: Conversation Node More experienced agent Transitions: # Issue resolved - Natural Language: "resolved" → Thank_And_Close # Needs management - Natural Language: "needs supervisor" OR {{customer_satisfaction}} < 3 → Level_3_Manager Level 3: Manager Type: Transfer Call Message: "Let me connect you with a supervisor who can help." Number: +1-800-MANAGERS ``` ## Router Node Configuration ### Building Conditions **Comparison Operators:** ```yaml theme={null} Equals: {{variable}} == "value" Not Equals: {{variable}} != "value" Greater Than: {{variable}} > 100 Less Than: {{variable}} < 100 Greater or Equal: {{variable}} >= 100 Less or Equal: {{variable}} <= 100 Contains: {{variable}} contains "keyword" In List: {{variable}} IN ["value1", "value2", "value3"] ``` **Logical Operators:** ```yaml theme={null} AND: {{condition1}} == true AND {{condition2}} == true OR: {{condition1}} == true OR {{condition2}} == true NOT: NOT {{condition1}} Complex: ({{tier}} == "VIP" OR {{balance}} > 10000) AND {{issue_type}} != "billing" ``` **Examples:** ```yaml theme={null} # VIP customers with urgent issues Condition: {{customer_tier}} == "VIP" AND {{urgency}} == "high" → VIP_Priority_Queue # New customers or high-value opportunities Condition: {{customer_type}} == "new" OR {{opportunity_value}} > 50000 → Sales_Team # Weekend or after hours Condition: {{current_weekday}} IN ["Saturday", "Sunday"] OR {{current_time}} > "17:00" OR {{current_time}} < "09:00" → After_Hours_Menu # Account issues requiring verification Condition: {{issue_type}} == "account_access" AND {{verified}} != true → Verification_Flow ``` ### Condition Ordering **Order matters! First match wins.** ```yaml theme={null} ❌ Wrong Order: Router: Conditions: - Always → General_Support - {{tier}} == "VIP" → VIP_Support # Never reached! ✓ Correct Order: Router: Conditions: - {{tier}} == "VIP" → VIP_Support - Always → General_Support ``` **Best Practice Ordering:** ```yaml theme={null} Router: Proper_Order Conditions: # 1. Most specific conditions first - {{tier}} == "VIP" AND {{issue}} == "critical" → VIP_Critical # 2. Then specific but less critical - {{tier}} == "VIP" → VIP_Standard # 3. Then general conditions - {{issue}} == "critical" → Critical_Support # 4. Catch-all last - Always → General_Support ``` ## Testing Routing Logic ### Testing Checklist Verify every condition can be reached * Boundary values (e.g., exactly 100) * Missing variables * Null values * Empty strings Ensure specific conditions before general Verify "Always" catches everything else Confirm variables populate correctly ### Common Issues **Causes:** * Variable not extracted * Variable name typo * Wrong comparison operator * Case sensitivity issue **Debug:** * Check variable value in logs * Verify variable name exactly matches * Test with simpler condition * Add logging/debugging node **Causes:** * Condition ordering wrong * Too broad condition earlier * Variable contains unexpected value **Debug:** * Review condition order * Check actual variable values * Make conditions more specific **Causes:** * Missing "Always" fallback * All conditions too specific **Solution:** * Always include "Always" fallback * Review conditions for gaps ## Complete Examples ### Example 1: E-commerce Support Router ```yaml theme={null} Entry: Collect_Intent Message: "How can I help you today?" Extract: caller_intent Router: Main_Router Conditions: # Order tracking (most common) - {{caller_intent}} contains "order" OR {{caller_intent}} contains "tracking" OR {{caller_intent}} contains "delivery" → Order_Tracking_Flow # Returns (second most common) - {{caller_intent}} contains "return" OR {{caller_intent}} contains "refund" OR {{caller_intent}} contains "exchange" → Returns_Flow # Product questions - {{caller_intent}} contains "product" OR {{caller_intent}} contains "information" → Product_Info_Flow # Account issues - {{caller_intent}} contains "account" OR {{caller_intent}} contains "login" OR {{caller_intent}} contains "password" → Account_Support_Flow # Speak to human - {{caller_intent}} contains "representative" OR {{caller_intent}} contains "person" OR {{caller_intent}} contains "agent" → Transfer_To_Agent # Fallback - Always → General_Support ``` ### Example 2: Healthcare Appointment Router ```yaml theme={null} Entry: Verify_Identity Message: "For your privacy, please enter your date of birth as 8 digits. For example, January 15th, 1990 would be 01-15-1990." DTMF Input Capture: Variable: date_of_birth Digit Limit: 8 Tool: Verify_Patient API: https://api.healthsystem.com/verify Parameters: dob: {{date_of_birth}} phone: {{user_number}} Returns: - patient_verified - patient_name - has_upcoming_appointments Router: Verified_Router Conditions: # Not verified - {{patient_verified}} == false → Manual_Verification # Has upcoming appointment (likely calling about it) - {{has_upcoming_appointments}} == true → Upcoming_Appointment_Options # Verified, no upcoming appointments - Always → Main_Menu Upcoming_Appointment_Options: Message: "Hello {{patient_name}}. I see you have an appointment coming up. Are you calling about: Press 1 to confirm your appointment Press 2 to reschedule Press 3 to cancel Press 4 for something else" Main_Menu: Message: "How can I help you? Press 1 to schedule an appointment Press 2 for prescription refills Press 3 for test results Press 4 to speak with a nurse" ``` ### Example 3: Multi-Department Company Router ```yaml theme={null} Entry: Welcome Message: "Thank you for calling Acme Corporation." Router: Time_Check Conditions: - {{current_weekday}} IN ["Saturday", "Sunday"] → Weekend_Flow - {{current_time}} < "09:00" OR {{current_time}} > "17:00" → After_Hours_Flow - Always → Business_Hours_Flow Business_Hours_Flow: Message: "For Sales, press 1. For Support, press 2. For Billing, press 3. For Human Resources, press 4. For our directory, press 5. Or stay on the line for the operator." Transitions: - DTMF: 1 → Sales_Router - DTMF: 2 → Support_Router - DTMF: 3 → Billing_Router - DTMF: 4 → HR_Router - DTMF: 5 → Directory_Search - Timeout 15s → Operator_Transfer Sales_Router: Conditions: - {{caller_number}} IN existing_customers → Account_Manager - Always → New_Sales_Team Support_Router: Message: "Is this a technical issue or product question?" Extract: support_type Conditions: - {{support_type}} contains "technical" → Tech_Support - {{support_type}} contains "product" → Product_Support - Always → General_Support After_Hours_Flow: Message: "You've reached us outside business hours. Press 1 for our automated account information system. Press 2 to leave a message for Sales. Press 3 to leave a message for Support. Press 0 for our emergency hotline." ``` ## Next Steps Build interactive menu systems Collect data to inform routing decisions Learn about the variable system Master flow-based agent design # Data Collection Guide Source: https://docs.tryhamsa.com/developers/agent-guides/data-collection Collect information with DTMF input capture, variables, and natural language extraction ## Overview Effective data collection is essential for voice agents that need to gather information from callers. Hamsa provides multiple methods to collect, validate, and use data throughout conversations, from simple name collection to complex multi-field forms. **Data Collection Methods:** * **Natural Language Extraction** - AI extracts data from spoken conversation * **DTMF Input Capture** - Collect digits via keypad * **Structured Prompting** - Guide users to provide specific information * **Variables** - Store and reference collected data ## Collection Methods ### 1. Natural Language Extraction The most natural method - AI extracts information from conversation. **How It Works:** 1. User speaks naturally 2. AI identifies and extracts specific data 3. Data stored in variables 4. Available for use throughout the flow **Example: Collecting Customer Information** ```yaml theme={null} Conversation Node: Collect_Info Message: "I'll need a few details to help you. What's your name and phone number?" Variable Extraction: - Variable: customer_name Instructions: "Extract the customer's full name" - Variable: phone_number Instructions: "Extract phone number in format XXX-XXX-XXXX" User Response: "My name is John Smith and my number is 555-123-4567" Extracted: customer_name: "John Smith" phone_number: "555-123-4567" ``` **Best For:** * Names, addresses, email addresses * Dates and times (flexible formats) * Free-form descriptions * Complex multi-field responses * Natural conversation flow **Advantages:** * Natural user experience * Flexible input formats * Handles variations well * No learning curve for users **Disadvantages:** * Potential transcription errors * Format inconsistencies * Requires validation * May need clarification ### 2. DTMF Input Capture Collect precise numeric data via keypad. **How It Works:** 1. Agent prompts for numeric input 2. User enters digits on keypad 3. System captures key presses 4. Stores in variable **Example: Account Number Collection** ```yaml theme={null} Conversation Node: Get_Account Message: "Please enter your 10-digit account number, followed by the pound key." DTMF Input Capture: Enabled: true Variable: account_number Digit Limit: 10 Termination Key: # Timeout: 15 seconds User Input: 1-2-3-4-5-6-7-8-9-0-# Result: account_number: "1234567890" ``` **Best For:** * Account numbers * Phone numbers * ZIP codes * PINs and passwords * Social security numbers (last 4 digits) * Confirmation codes * Numeric IDs **Advantages:** * 100% accurate (no transcription errors) * Works in noisy environments * Familiar to users * Secure for sensitive data **Disadvantages:** * Numbers only (0-9) * Slower than speaking * Requires hands-free device awareness * Not accessible to all users ### 3. Guided Prompting Ask specific questions to collect structured data. **How It Works:** 1. Ask focused, single questions 2. Extract one piece of information 3. Confirm understanding 4. Move to next question **Example: Appointment Scheduling** ```yaml theme={null} Node 1: Get_Date Message: "What date would you like to schedule? For example, January 15th." Extract: appointment_date Node 2: Confirm_Date Message: "Got it, {{appointment_date}}. And what time works best for you?" Extract: appointment_time Node 3: Verify_All Message: "Perfect! I have you scheduled for {{appointment_date}} at {{appointment_time}}. Is that correct?" Extract: confirmation (yes/no) ``` **Best For:** * Multi-step forms * Complex data collection * Situations requiring validation * When precision matters **Advantages:** * Clear expectations * Easy to validate * Reduces errors * Good user experience **Disadvantages:** * Takes more time * Multiple conversational turns * Can feel rigid * Requires good flow design ## Variable System ### Defining Variables **Extracted Variables**: Collected during conversation **Custom Variables**: Passed via API when call starts **System Variables**: Built-in (time, caller ID, etc.) Use snake\_case format: * `customer_name` * `phone_number` * `appointment_date` * `order_number` Provide clear extraction instructions: * What to extract * Expected format * Examples if helpful Reference variable anywhere: * Prompts: `{{customer_name}}` * Tool parameters * Routing conditions ### Variable Naming Best Practices **Good Names:** ```yaml theme={null} ✓ customer_name ✓ email_address ✓ appointment_date ✓ order_number ✓ shipping_address ✓ phone_number ✓ account_balance ``` **Bad Names:** ```yaml theme={null} ✗ name (too vague) ✗ customerName (use snake_case, not camelCase) ✗ customer-name (no hyphens) ✗ Customer Name (no spaces or capitals) ✗ var1 (not descriptive) ✗ temp (unclear purpose) ``` ### Extraction Instructions **Clear Instructions:** ```yaml theme={null} ✓ "Extract the customer's full name" ✓ "Extract email address in format user@domain.com" ✓ "Extract appointment date in MM/DD/YYYY format" ✓ "Extract order number (starts with ORD-)" ✗ "Get the name" ✗ "Extract email" ✗ "Get the date" ``` **With Examples:** ```yaml theme={null} Variable: phone_number Instructions: "Extract 10-digit phone number. Examples: 555-123-4567, (555) 123-4567, 5551234567. Store in format: XXX-XXX-XXXX" Variable: appointment_date Instructions: "Extract date mentioned by caller. Examples: 'next Tuesday', 'January 15th', '1/15/2024'. Convert to YYYY-MM-DD format." ``` ## Complete Collection Workflows ### Example 1: Customer Registration Collect comprehensive customer information. ```yaml theme={null} Node 1: Welcome Message: "I'll help you create an account. This will just take a minute." Node 2: Collect_Name Message: "First, what's your full name?" Extract Variables: - customer_name: "Extract full name (first and last)" Node 3: Confirm_Name Message: "Thank you, {{customer_name}}. What's the best email address to reach you?" Extract Variables: - email_address: "Extract email in format user@domain.com" Node 4: Collect_Phone Message: "Great. And what's your phone number?" Extract Variables: - phone_number: "Extract 10-digit phone number" Node 5: Verify_Information Message: "Let me confirm your information: Name: {{customer_name}} Email: {{email_address}} Phone: {{phone_number}} Is everything correct?" Extract Variables: - confirmation: "Extract yes/no confirmation" Transitions: - confirmation == "yes" → Create_Account_Tool - confirmation == "no" → What_To_Change Node 6: Create_Account (Tool) Tool: create_customer_account Parameters: name: {{customer_name}} email: {{email_address}} phone: {{phone_number}} source: "phone" timestamp: {{current_datetime}} Node 7: Success Message: "Your account is all set, {{customer_name}}! You'll receive a confirmation email at {{email_address}}." ``` ### Example 2: Secure Authentication Collect sensitive information securely. ```yaml theme={null} Node 1: Request_Account Message: "For security, I'll need to verify your account. Please enter your account number using your keypad, followed by the pound key." DTMF Input Capture: Variable: account_number Digit Limit: 10 Termination Key: # Node 2: Request_PIN Message: "Thank you. Now please enter your 4-digit PIN." DTMF Input Capture: Variable: pin_code Digit Limit: 4 Timeout: 15s Node 3: Verify_Credentials (Tool) Tool: verify_account Parameters: account: {{account_number}} pin: {{pin_code}} call_id: {{call_id}} Transitions: - API returns success → Authenticated_Menu - API returns failure → Retry_Authentication - After 3 failures → Transfer_Security Node 4: Retry_Authentication Message: "I couldn't verify those credentials. Let's try again. Please enter your account number." Node 5: Authenticated_Menu Message: "Thank you for verifying your identity, {{customer_name}}. How can I help you today?" ``` ### Example 3: Hybrid Collection (DTMF + NL) Combine DTMF and natural language for optimal UX. ```yaml theme={null} Node 1: Collect_ZIP Message: "What's your ZIP code? You can say it or enter it on your keypad, followed by pound." DTMF Input Capture: Variable: zip_code Digit Limit: 5 Termination Key: # Extract Variables: - zip_code: "Extract 5-digit ZIP code if spoken" # Either method populates zip_code variable Node 2: Collect_Date Message: "What date would you like? You can say something like 'next Tuesday' or 'January 15th'." Extract Variables: - appointment_date: "Extract date, convert to YYYY-MM-DD" Node 3: Confirm_Details Message: "I have ZIP code {{zip_code}} and date {{appointment_date}}. Is that right?" ``` ### Example 4: Survey Data Collection Structured survey with validation. ```yaml theme={null} Survey Flow: Node 1: Introduction Message: "This quick survey takes about 2 minutes. Your feedback helps us improve." Node 2: Question_1 Message: "On a scale of 1 to 5, with 5 being very satisfied, how satisfied are you with our service? You can say the number or press it on your keypad." DTMF Input Capture: Variable: satisfaction_score Digit Limit: 1 Extract Variables: - satisfaction_score: "Extract number 1-5" Validation: - satisfaction_score must be 1-5 Node 3: Question_2 Message: "Would you recommend us to a friend? Yes or no?" Extract Variables: - would_recommend: "Extract yes or no" Node 4: Question_3 (Conditional) Condition: satisfaction_score < 3 Message: "I'm sorry to hear that. Can you tell me what we could improve?" Extract Variables: - improvement_feedback: "Extract detailed feedback" Node 5: Submit_Survey (Tool) Tool: submit_survey_results Parameters: satisfaction: {{satisfaction_score}} recommend: {{would_recommend}} feedback: {{improvement_feedback}} caller: {{user_number}} date: {{current_date}} Node 6: Thank_You Message: "Thank you for your feedback, we really appreciate it!" ``` ## Validation Strategies ### Format Validation Ensure data meets expected format. **Email Validation:** ```yaml theme={null} Node: Collect_Email Message: "What's your email address?" Extract Variables: - email_address: "Extract email in format user@domain.com" Validation Node: Condition: email_address contains "@" AND email_address contains "." If valid → Continue If invalid → "That doesn't look like a valid email. Could you spell it out for me? For example, john at example dot com." ``` **Phone Number Validation:** ```yaml theme={null} Validation Logic: - Length: Must be 10 digits - Format: (XXX) XXX-XXXX or XXX-XXX-XXXX or XXXXXXXXXX - Area code: First digit cannot be 0 or 1 Error Message: "I need a 10-digit phone number. For example, 555-123-4567. What's your phone number?" ``` **Date Validation:** ```yaml theme={null} Validation Logic: - Must be future date (for appointments) - Must be valid calendar date - Must be within acceptable range Error Message: "That date doesn't work. I can schedule appointments up to 6 months out. What date would you like?" ``` ### Range Validation Ensure values fall within acceptable ranges. ```yaml theme={null} Node: Collect_Age Message: "For verification, how old are you?" Extract Variables: - age: "Extract age as number" Validation: - age >= 18 AND age <= 120 → Valid - age < 18 → "I'm sorry, you must be 18 or older." - age > 120 → "That doesn't seem right. What's your age?" Node: Collect_Quantity Message: "How many would you like to order?" Extract Variables: - quantity: "Extract number" Validation: - quantity >= 1 AND quantity <= 100 → Valid - quantity < 1 → "I need at least 1 item." - quantity > 100 → "For orders over 100, please contact our sales team directly." ``` ### Existence Validation Verify data exists in system. ```yaml theme={null} Node: Collect_Order_Number Message: "What's your order number?" Extract Variables: - order_number: "Extract order number (format ORD-XXXXX)" Validation Tool: Tool: check_order_exists Parameters: order_number: {{order_number}} Transitions: - Order found → Display_Order_Info - Order not found → "I couldn't find that order number. Can you double-check and try again?" - After 3 attempts → "Let me transfer you to customer service." ``` ## Handling Collection Errors ### Transcription Errors Speech recognition isn't perfect. **Strategy: Confirmation** ```yaml theme={null} Node: Collect_Email Message: "What's your email address?" Extract: email_address Node: Confirm_Email Message: "I heard {{email_address}}. Is that correct?" Extract: confirmation Transitions: - "yes" → Continue - "no" → "Let's try again. Can you spell it out? For example, J-O-H-N at G-M-A-I-L dot com." ``` **Strategy: Phonetic Spelling** ```yaml theme={null} After Error: "I'm having trouble hearing that. Let me try a different way. Can you spell your email letter by letter? For example, J for John, O for Oscar, H for Hotel..." Extract as: Phonetic sequence Convert to: email_address ``` ### Ambiguous Input User provides unclear information. ```yaml theme={null} Node: Collect_Date Message: "What date would you like?" User: "Soon" Problem: Too vague Response: "I can schedule appointments starting tomorrow through the next 6 months. What specific date works for you? For example, next Monday, or January 15th?" User: "Monday" Problem: Which Monday? Response: "Did you mean Monday, January 15th, or Monday, January 22nd?" ``` ### Incomplete Information User doesn't provide all needed data. ```yaml theme={null} Node: Collect_Address Message: "What's your street address?" User: "123 Main Street" Problem: No city, state, ZIP Solution: Follow-up questions "And what city is that in?" "What's the ZIP code?" Or: Structured prompting "I'll need your complete address. What's the street address?" [collect] "And the city?" [collect] "State?" [collect] "ZIP code?" ``` ## Advanced Techniques ### Multi-Slot Extraction Extract multiple fields from one response. ```yaml theme={null} Node: Collect_All_At_Once Message: "To send you a quote, I'll need your email and phone number." Extract Variables: - email_address: "Extract email address" - phone_number: "Extract phone number" User: "My email is john@example.com and you can reach me at 555-1234" Extracted: email_address: "john@example.com" phone_number: "555-1234" Validation Node: Check both variables: - If email exists AND phone exists → Continue - If only email → "Great! And your phone number?" - If only phone → "Got it. And your email address?" - If neither → "Let me ask separately. What's your email?" ``` ### Conditional Collection Collect different data based on context. ```yaml theme={null} Router: Account_Type_Check Condition: {{account_type}} == "business" → Collect business-specific info (EIN, company name) Condition: {{account_type}} == "personal" → Collect personal info (SSN last 4, DOB) Business Info Collection: - company_name - ein_number - business_address Personal Info Collection: - ssn_last_four - date_of_birth - home_address ``` ### Progressive Profiling Collect more data over multiple interactions. ```yaml theme={null} First Call: - Collect: name, phone, email - Create basic profile Second Call: - Already have: name, phone, email - Collect: preferences, interests Third Call: - Already have: basic info, preferences - Collect: detailed requirements ``` ### Context-Aware Collection Use available context to skip collection. ```yaml theme={null} Router: Check_Existing_Data Condition: {{user_number}} in customer_database → Lookup customer data → "Welcome back, {{customer_name}}! I have your email as {{email_address}}. Is that still correct?" Condition: {{user_number}} NOT in customer_database → "I don't have your information yet. What's your name?" → Full collection flow ``` ## Data Storage & Usage ### Storing Collected Data **During Call:** ```yaml theme={null} Variables stored in call context: - Available throughout conversation - Passed between nodes - Used in tools and routing - Included in call logs ``` **After Call:** ```yaml theme={null} Method 1: Webhooks - Send data to your server - Store in your database - Trigger workflows Method 2: Outcomes - Define outcome schema - Automatically extract at call end - Retrieve via API Method 3: Tools - Call your API during conversation - Store data real-time - Return confirmation ``` ### Using Collected Data **In Prompts:** ```yaml theme={null} 'Thank you, {{customer_name}}! Your order {{order_number}} will be shipped to {{shipping_address}}.' ``` **In Tools:** ```yaml theme={null} Tool: create_customer Parameters: name: { { customer_name } } email: { { email_address } } phone: { { phone_number } } source: 'phone_call' collected_at: { { current_datetime } } ``` **In Routing:** ```yaml theme={null} Router: Priority_Check Condition: {{customer_tier}} == "VIP" → VIP_Fast_Track Condition: {{issue_severity}} == "high" → Urgent_Support Default → Standard_Support ``` **In Webhooks:** ```json theme={null} { "event": "call.ended", "data": { "customer_name": "{{customer_name}}", "email_address": "{{email_address}}", "phone_number": "{{phone_number}}", "issue_type": "{{issue_type}}", "resolution": "{{resolution_status}}" } } ``` ## Troubleshooting **Check:** * Extraction instructions are clear * User actually provided the information * Variable name is correct (snake\_case) * Extraction is enabled on the node **Solutions:** * Make instructions more specific * Add examples to instructions * Ask more directly for the information **Check:** * Transcription accuracy * Extraction instructions specificity * User response clarity **Solutions:** * Add format specifications to instructions * Confirm what was heard * Use DTMF for critical data **Check:** * DTMF Input Capture is enabled * Variable name is set * At least one completion condition configured * Testing with actual phone (not browser) **Solutions:** * Enable DTMF Input Capture toggle * Set variable name * Add termination key or digit limit ## Next Steps Learn more about the variable system Deep dive into DTMF input capture Send collected data to your systems Route calls based on collected data # Building IVR Menus Source: https://docs.tryhamsa.com/developers/agent-guides/ivr-menus Create interactive voice response menus with DTMF ## Overview Interactive Voice Response (IVR) menus allow callers to navigate options using their phone keypad. Hamsa makes it easy to build sophisticated IVR systems that combine traditional DTMF menu navigation with AI-powered conversation. **What You'll Learn:** * Building traditional IVR menus with DTMF * Combining IVR with conversational AI * Best practices for menu design * Advanced multi-level menu structures * Accessibility and user experience ## IVR Fundamentals ### What is IVR? IVR (Interactive Voice Response) is a telephony technology that allows callers to interact with a phone system through voice or keypad input. In Hamsa, you can build IVR menus using: * **DTMF (Dual-Tone Multi-Frequency)** - Keypad button presses * **Natural Language** - Spoken responses understood by AI * **Hybrid** - Combination of both ### DTMF Keys Available **Standard Keys:** * **0-9** - Numeric keys * **\*** (Star) - Often used for "back" or special functions * **#** (Pound/Hash) - Often used for "confirm" or "submit" **Common Conventions:** ``` 0 = Operator/Human Agent 1-9 = Menu options * = Go back/Previous menu # = Confirm/Submit/Continue ``` ## Building Your First IVR Menu ### Simple Two-Option Menu Let's build a basic menu: "Press 1 for Sales, Press 2 for Support" Navigate to **Agents** → **Create New Agent** → **Flow Agent** Set the greeting message: ``` "Thank you for calling Acme Corporation. Press 1 for Sales, or Press 2 for Support." ``` On the Start node: * Click **Add Transition** * Select **DTMF** as transition type * Click key **1** on the keypad * Label: "Press 1" * Add a new Conversation node * Connect the "Press 1" transition to it * Set message: "Connecting you to Sales..." * Add transition for key **2** * Create Support node * Connect transition Test the flow by pressing 1 or 2 during the greeting **Flow Diagram:** ```mermaid theme={null} graph LR Start[Start: Press 1 or 2] -->|DTMF: 1| Sales[Sales Department] Start -->|DTMF: 2| Support[Support Department] ``` ### Adding Natural Language Fallback Enhance your menu to accept both DTMF and spoken responses: ```yaml theme={null} Start Node: Message: "Thank you for calling Acme Corporation. Press 1 or say 'Sales' for our sales team. Press 2 or say 'Support' for customer support." Transitions: - Type: DTMF, Key: 1 → Sales Node - Type: DTMF, Key: 2 → Support Node - Type: Natural Language, Condition: "caller mentions sales" → Sales Node - Type: Natural Language, Condition: "caller mentions support" → Support Node - Type: Always (Fallback) → Clarification Node ``` **Hybrid Approach Benefits:** * Accessible to users who prefer keypad * Natural for users who prefer speaking * Faster navigation for power users * Better accessibility compliance ## Multi-Level Menu Structures ### Three-Level Menu Example Build a comprehensive support system: **Level 1: Main Menu** ```yaml theme={null} Main Menu Node: Message: 'Welcome to Acme Support. Press 1 for Product Support. Press 2 for Billing Questions. Press 3 for Technical Support. Press 0 to speak with an operator.' Transitions: - DTMF: 1 → Product Support Menu - DTMF: 2 → Billing Menu - DTMF: 3 → Technical Support Menu - DTMF: 0 → Operator Transfer ``` **Level 2: Product Support Sub-Menu** ```yaml theme={null} Product Support Menu: Message: "Product Support. Press 1 for Software Products. Press 2 for Hardware Products. Press 3 for Accessories. Press * to return to the main menu." Transitions: - DTMF: 1 → Software Support - DTMF: 2 → Hardware Support - DTMF: 3 → Accessories Support - DTMF: * → Main Menu ``` **Level 3: Specific Product Support** ```yaml theme={null} Software Support Node: Message: "Software Support. Press 1 for installation help. Press 2 for licensing questions. Press 3 for troubleshooting. Press * to go back." Transitions: - DTMF: 1 → Installation Agent - DTMF: 2 → Licensing Agent - DTMF: 3 → Troubleshooting Agent - DTMF: * → Product Support Menu ``` **Visual Flow:** ``` Main Menu ├─ 1: Product Support │ ├─ 1: Software │ │ ├─ 1: Installation │ │ ├─ 2: Licensing │ │ └─ 3: Troubleshooting │ ├─ 2: Hardware │ └─ 3: Accessories ├─ 2: Billing ├─ 3: Technical Support └─ 0: Operator ``` ### Managing Menu Depth **Don't Go Too Deep** * Maximum 3 levels recommended * Users get lost beyond 3 levels * Each level increases abandonment risk * Consider conversational AI for complex routing **When to use deep menus:** * Large organization with many departments * Complex product catalog * Specialized support teams * Compliance requirements **When to use conversational AI instead:** * Fewer than 10 total options * Options require explanation * User intent is ambiguous * Better user experience desired ## Global DTMF Triggers Create shortcuts accessible from anywhere in the call. ### Setting Up Global Shortcuts **Operator Transfer (Always Available)** Add a Transfer Call node to your flow In node settings: * Toggle **Global** ON * Select trigger type: **DTMF** * Choose key: **0** * Phone number: `+1-800-OPERATOR` * Message: "Transferring you to an operator..." **Result:** Users can press 0 at any point to reach an operator. ### Common Global Shortcuts ```yaml theme={null} Global Shortcuts: Press 0: Operator Transfer Type: Transfer Call Node Global: Yes DTMF Key: 0 Message: "Connecting you to an operator..." Press 9: Repeat Menu Type: Conversation Node Global: Yes DTMF Key: 9 Message: "Main menu: Press 1 for Sales, 2 for Support..." Press *: Go Back Type: Router Node Global: Yes DTMF Key: * Logic: Return to previous menu (context-aware) Press #: Main Menu Type: Conversation Node Global: Yes DTMF Key: # Message: "Returning to main menu..." ``` **Global Triggers Best Practices:** * Always offer 0 for operator * Use 9 for menu repeat * Use \* for back/previous * Use # for main menu/start over * Announce these options in welcome greeting ## Advanced Menu Patterns ### Time-Based Routing Route calls differently based on time of day: ```yaml theme={null} Start Node: Message: "Thank you for calling Acme Corporation." Router Node: Time Check Conditions: - {{current_weekday}} IN ["Saturday", "Sunday"] → Weekend Menu - {{current_time}} < "09:00" → After Hours Menu - {{current_time}} > "17:00" → After Hours Menu - Always → Business Hours Menu Weekend Menu: Message: "Our offices are closed on weekends. Press 1 to leave a message. Press 2 for emergency support. Press 3 to hear our business hours." Business Hours Menu: Message: "Press 1 for Sales. Press 2 for Support. Press 3 for Billing." ``` ### Language Selection Menu Offer multi-language support: ```yaml theme={null} Language Selection Node: Message: 'Thank you for calling Acme Corporation. For English, press 1. Para Español, oprima el dos. Pour le Français, appuyez sur le trois.' Transitions: - DTMF: 1 → English Menu - DTMF: 2 → Spanish Menu - DTMF: 3 → French Menu English Menu: Language: en-US Voice: aura-asteria-en Message: 'Welcome! How can I help you today?' Spanish Menu: Language: es-MX Voice: aura-sofia-es Message: 'Bienvenido! ¿Cómo puedo ayudarte hoy?' ``` ### Priority Routing Menu Fast-track VIP or urgent calls: ```yaml theme={null} Priority Menu: Message: "Thank you for calling. If this is an emergency, press 1 now. If you're a VIP member, press 2. For all other callers, press 3." Transitions: - DTMF: 1 → Emergency Transfer (Immediate) - DTMF: 2 → VIP Verification → VIP Queue - DTMF: 3 → Standard Menu ``` ### Callback Offer Menu Reduce wait times with callback option: ```yaml theme={null} Queue Status Node: Message: 'All agents are currently busy. Your estimated wait time is {{estimated_wait}} minutes. Press 1 to hold. Press 2 to request a callback. Press 3 to leave a voicemail.' Transitions: - DTMF: 1 → Hold Music Node - DTMF: 2 → Callback Collection Flow - DTMF: 3 → Voicemail Node ``` ## Menu Design Best Practices ### Clear Menu Announcements **Good:** ``` "Press 1 for Sales. Press 2 for Support." ``` **Bad:** ``` "If you're interested in learning more about our products, speaking with a sales representative, getting a quote, or discussing pricing, please press 1. If you're experiencing technical difficulties, need help with your account, want to report a problem, or have general questions about using our service, please press 2." ``` **Why:** Callers forget early options by the time you finish. **Recommended:** 3-5 options per menu **Maximum:** 7 options **Why:** * Human working memory limit * Reduces cognitive load * Faster decision making * Lower abandonment rate **If you have 10+ options:** * Break into sub-menus * Use conversational AI instead * Prioritize most common options **Put most common options first:** ``` "Press 1 for Customer Support (80% of calls) Press 2 for Sales (15% of calls) Press 3 for Billing (5% of calls)" ``` **Consider priority:** ``` "If this is an emergency, press 1. For all other calls, press 2." ``` **Alphabetical can work:** ``` "Press 1 for Accounting Press 2 for Billing Press 3 for Customer Service" ``` **Include in every menu:** ``` "...or press 0 to speak with an operator." ``` **Why:** * Required by many regulations * Accessibility requirement * Handles edge cases * Reduces frustration * Improves satisfaction ### Menu Pacing **Timing Recommendations:** ```yaml theme={null} Menu Timing: Pause after greeting: 0.5 seconds Pause between options: 0.3 seconds Pause before repeat: 1.0 seconds Wait for input: 5-10 seconds Timeout after: 10 seconds Example: "Thank you for calling Acme." [0.5s pause] "Press 1 for Sales." [0.3s pause] "Press 2 for Support." [0.3s pause] "Or press 0 for an operator." [Wait 10s for input] ``` ### Repeat and Replay Options **Automatic Repeat:** ```yaml theme={null} Menu Node: Message: "Press 1 for Sales, 2 for Support." Timeout Handling: After 10s silence: "I didn't receive a selection. Press 1 for Sales, 2 for Support, or 0 for an operator." After 2nd timeout: "I'll transfer you to an operator who can help." → Transfer to Operator ``` **Manual Repeat:** ```yaml theme={null} Global Repeat Menu Node: Global: Yes DTMF Key: 9 Message: 'Main menu: Press 1 for Sales, 2 for Support, 3 for Billing, or 0 for an operator.' ``` ## Error Handling ### Invalid Input Handling ```yaml theme={null} Menu Node: Message: "Press 1 for Sales or 2 for Support." Invalid Input Node: Message: "I didn't recognize that selection. Press 1 for Sales or 2 for Support." After 2 invalid attempts: "Let me connect you with someone who can help." → Transfer to Operator ``` ### No Input Handling ```yaml theme={null} No Input Strategy: First timeout (10s): "Are you still there? Press any key to continue, or I can connect you with an operator." Second timeout (10s): "I haven't heard from you. I'll transfer you to someone who can assist." → Transfer to Operator Third timeout (10s): "Thank you for calling. Goodbye." → End Call ``` ### Wrong Menu Navigation ```yaml theme={null} Wrong Menu Detection: If caller presses invalid key multiple times: "It seems like you're having trouble with the menu. Let me connect you to an operator." → Transfer If caller says "operator" or "representative": → Bypass menu, transfer immediately If caller says "I don't know" or similar: "No problem! Let me ask you a few questions to help." → Conversational routing ``` ## Combining IVR with AI ### Hybrid Menu Pattern Best of both worlds: structure + flexibility ```yaml theme={null} Hybrid Menu Node: Message: "Thank you for calling Acme. You can press a number or just tell me what you need. Press 1 for Sales. Press 2 for Support. Or simply tell me how I can help." Transitions: - DTMF: 1 → Sales - DTMF: 2 → Support - Natural Language: "mentions sales, pricing, quote" → Sales - Natural Language: "mentions problem, issue, help" → Support - Natural Language: "any other input" → AI Router AI Router Node: Type: Conversation Prompt: "Understand what the caller needs and route appropriately." Transitions: - Condition: "sales related" → Sales - Condition: "support related" → Support - Condition: "unclear" → Clarification ``` ### Smart Menu Skip Skip menus for known callers: ```yaml theme={null} Entry Point: Router: Check Caller History Conditions: - {{user_number}} IN known_customers AND {{last_call_reason}} == "support" → "Welcome back! Are you calling about the same issue?" → Support (skip menu) - {{is_vip}} == true → "Welcome, {{customer_name}}. How can I help you today?" → VIP Agent (skip menu) - Always → → Main Menu ``` ### Conversational Menu Navigation Let AI handle complex menu structures: ```yaml theme={null} AI Menu Navigator: Message: 'What can I help you with today?' Agent Prompt: 'The caller can ask for: - Sales (route to sales team) - Support (ask for product type, then route) - Billing (verify account, then route) - General info (answer directly) Classify their intent and route appropriately. If unclear, ask one clarifying question.' Transitions: Based on AI classification → Appropriate department ``` ## Complete IVR Examples ### Example 1: Small Business Reception ```yaml theme={null} Main Menu: Message: "Thank you for calling Acme Services. Press 1 for our Business Hours and Location. Press 2 to Schedule an Appointment. Press 3 for Billing Questions. Or press 0 to speak with someone. You can also just tell me what you need." DTMF Transitions: 1 → Business Info 2 → Appointment Scheduler 3 → Billing Department 0 → Receptionist Natural Language: "mentions hours, location, address" → Business Info "mentions appointment, schedule, book" → Appointment Scheduler "mentions bill, payment, invoice" → Billing Department Other → Receptionist Business Info Node: Message: "We're open Monday through Friday, 9 AM to 5 PM. We're located at 123 Main Street, Suite 100. Would you like directions? Press 1 for yes, 2 for no." Transitions: DTMF: 1 → Send Directions (SMS/Email) DTMF: 2 → Main Menu ``` ### Example 2: Healthcare Clinic ```yaml theme={null} Main Menu: Message: "Welcome to City Health Clinic. If this is a medical emergency, hang up and dial 911. To schedule or change an appointment, press 1. For prescription refills, press 2. For test results, press 3. For billing, press 4. For all other questions, press 5." Transitions: DTMF: 1 → Appointment System DTMF: 2 → Prescription Refills DTMF: 3 → Test Results (requires verification) DTMF: 4 → Billing DTMF: 5 → Nurse Line Appointment System: Message: "Appointment scheduling. Press 1 for a new appointment. Press 2 to change an existing appointment. Press 3 to cancel an appointment." Transitions: DTMF: 1 → New Appointment Flow DTMF: 2 → Change Appointment Flow DTMF: 3 → Cancel Appointment Flow ``` ### Example 3: E-commerce Order Status ```yaml theme={null} Main Menu: Message: "Thank you for calling ShopNow. Press 1 to track your order. Press 2 for returns and exchanges. Press 3 to speak with customer service. Or you can say your order number, and I'll look it up for you." Transitions: DTMF: 1 → Order Tracking DTMF: 2 → Returns Menu DTMF: 3 → Customer Service Natural Language: Extract order number → Direct Lookup Order Tracking: Message: "Please enter your order number using your keypad, followed by the pound key. Or you can say it." DTMF Input Capture: Variable: order_number Termination Key: # Digit Limit: 10 Transitions: Always → Lookup Order Tool → Order Status Response ``` ## Testing IVR Menus ### Test Checklist * [ ] **All DTMF keys work** * Test each number (0-9) * Test \* and # if used * Verify transitions go to correct nodes * [ ] **Menu audio is clear** * Options easily understood * Proper pacing between options * Professional voice quality * [ ] **Timeouts handled gracefully** * Test silence handling * Verify repeat behavior * Confirm timeout transfers work * [ ] **Error handling works** * Test invalid key presses * Verify multiple errors escalate * Check error messages are helpful * [ ] **Global shortcuts functional** * Test 0 for operator from every menu * Test \* for back if implemented * Verify shortcuts work globally * [ ] **Navigation is intuitive** * Users can find what they need * Menus aren't too deep * Back navigation works * Can return to main menu ### Common Issues **Problem:** Callers forget options **Solution:** * Limit to 5 options max * Break into sub-menus * Use AI routing instead **Problem:** DTMF not detected **Solution:** * Check DTMF transitions configured * Verify key selection in builder * Test with actual phone (not just browser) * Check network supports DTMF **Problem:** Too many levels or unclear options **Solution:** * Simplify menu structure * Add "press 9 to repeat" option * Provide operator option * Add breadcrumb navigation ## Accessibility Considerations **Make IVR Accessible:** * Always provide operator option (0) * Support speech input, not just DTMF * Clear, slow menu announcements * Repeat options on request * Handle timeouts gracefully * Provide alternative contact methods ## Next Steps Deep dive into DTMF capabilities Collect information with DTMF input Advanced routing patterns Build complex conversation flows # Live kit plugin Source: https://docs.tryhamsa.com/developers/agent-guides/live-kit-plugin # Hamsa LiveKit Integration A [LiveKit integration](https://github.com/hamsa-ai/hamsa_livekit) for Hamsa AI's advanced Arabic speech technology, providing state-of-the-art Speech-to-Text (STT) and Text-to-Speech (TTS) capabilities with support for multiple Arabic dialects. ## 🌟 Features * **🎙️ Advanced Arabic STT**: High-accuracy speech recognition across Arabic dialects * **🔊 Natural Arabic TTS**: Lifelike text-to-speech with 24 Arabic voices * **🌍 Multi-Dialect Support**: 9 Arabic dialects supported * **⚡ Real-time Processing**: Low-latency streaming for live conversations * **🤖 LiveKit Agent Integration**: Seamless integration with LiveKit's agent framework ## 🚀 Installation ### 1. Clone the Repository ```bash theme={null} git clone https://github.com/hamsa-ai/hamsa_livekit.git cd hamsa_livekit pip install -e . ``` ### 2. Configuration Create a `.env` file: ```env theme={null} # LiveKit Configuration LIVEKIT_API_KEY=your_livekit_api_key LIVEKIT_API_SECRET=your_livekit_api_secret LIVEKIT_URL=wss://your-project.livekit.cloud # Hamsa AI Configuration HAMSA_API_KEY=your_hamsa_api_key ``` ## 🔧 Usage ### Basic LiveKit Agent with Hamsa ```python theme={null} from dotenv import load_dotenv from livekit import agents from livekit.agents import AgentSession, Agent, RoomInputOptions from livekit.plugins import openai, noise_cancellation, silero import hamsa_livekit load_dotenv() class HamsaAssistant(Agent): def __init__(self) -> None: super().__init__(instructions="You are a helpful Arabic voice assistant.") async def entrypoint(ctx: agents.JobContext): await ctx.connect() # Create agent session with Hamsa STT and TTS session = AgentSession( stt=hamsa_livekit.STT(language="ar"), llm=openai.LLM(model="gpt-4.1"), tts=hamsa_livekit.TTS(speaker="Lana", dialect="jor"), vad=silero.VAD.load(), turn_detection="vad", ) await session.start( room=ctx.room, agent=HamsaAssistant(), room_input_options=RoomInputOptions( noise_cancellation=noise_cancellation.BVC(), ), ) await session.generate_reply( instructions="Greet the user in Arabic and offer your assistance." ) if __name__ == "__main__": agents.cli.run_app(agents.WorkerOptions(entrypoint_fnc=entrypoint)) ``` ### Configuration Options #### STT Configuration ```python theme={null} stt = hamsa_livekit.STT( language="ar", # Arabic language code api_key=None, # Optional API key override base_url="...", # Optional base URL override http_session=None # Optional HTTP session ) ``` #### TTS Configuration ```python theme={null} tts = hamsa_livekit.TTS( speaker="Ali", # Voice speaker name (default: "Ali") dialect="pls", # Dialect code (default: "pls") mulaw=False, # μ-law encoding (default: False) sample_rate=16000, # Audio sample rate (default: 16000) api_key=None, # Optional API key override base_url="...", # Optional base URL override word_tokenizer=None, # Optional word tokenizer http_session=None # Optional HTTP session ) ``` ## 🎙️ Available Voices & Dialects ### Speakers (around 99 voices available) Those are some voices examples and the the corresponding dialects in the below table: `Amjad`, `Aml`, `Salma`, `Mariam`, `Dalal`, `Lana`, `Omar`, `Jasem`, `Samir`, `Carla`, `Nada`, `Mais`, `Fatma`, `Hiba`, `Ali`, `Layan`, `Saly`, `Mazen`, `Hafsa`, `Dima`, `Majd`, `Talin`, `Ahmed`, `Rema`, `Fahd`, `Rami` You can get more voices from one of our platforms, on Hamsa Agents, click [here](https://agents.tryhamsa.com/app/voices) to get you there, and [here](https://media.tryhamsa.com/app/voices) to get you to the voices page on Hamsa Media. ### Dialects & Recommended Voices | Dialect | Code | Some of the Recommended Voices | | ----------- | ----- | -------------------------------- | | Palestinian | `pls` | Amjad, Layan, Talin, Rema, Obida | | Lebanese | `leb` | Carla, Majd | | Jordanian | `jor` | Lana, Omar, Nada | | Syrian | `syr` | Dalal, Mais | | Saudi | `ksa` | Hiba, Saly, Fahd, Jasem | | Bahraini | `bah` | Mazen, Hafsa | | Emirati | `uae` | Salma, Dima | | Egyptian | `egy` | Mariam, Samir, Ali, Ahmed | | Iraqi | `irq` | Aml, Fatma | ## 📝 Quick Examples ### STT-Only Agent ```python theme={null} session = AgentSession( stt=hamsa_livekit.STT(language="ar"), llm=None, tts=None, vad=silero.VAD.load(), turn_detection="vad", ) ``` ### TTS-Only Agent ```python theme={null} session = AgentSession( stt=None, llm=openai.LLM(model="gpt-4.1"), tts=hamsa_livekit.TTS(speaker="Mariam", dialect="egy"), vad=silero.VAD.load(), turn_detection="vad", ) ``` ### Custom Audio Settings ```python theme={null} # High-quality TTS with custom sample rate tts = hamsa_livekit.TTS( speaker="Amjad", dialect="pls", sample_rate=24000, # Higher quality mulaw=True # μ-law encoding ) ``` ## 🛠️ Running Your Agent ```bash theme={null} # Basic run python your_agent.py dev # With specific room python your_agent.py connect --room your-room-name --token your-token ``` ## 🆘 Support * **API Reference**: [docs.tryhamsa.com/api-reference/introduction](https://docs.tryhamsa.com/api-reference/introduction) * **Email**: [support@tryhamsa.com](mailto:support@tryhamsa.com) # Prompt Engineering Guide Source: https://docs.tryhamsa.com/developers/agent-guides/prompt-engineering Write effective prompts for voice AI agents Learn best practices for writing prompts that create natural, effective voice AI conversations. ## What You'll Learn * Prompt structure and components * Voice-specific prompt techniques * Handling edge cases and errors * Testing and iterating on prompts * Advanced prompt patterns * Common pitfalls to avoid ## Coming Soon This guide is being migrated from the [Prompt Engineering overview](/overview/guides/prompt-engineering). Full content will include: * Complete prompt templates * Voice-optimized examples * A/B testing strategies * Prompt versioning best practices For now, refer to the original [Prompt Engineering guide](/overview/guides/prompt-engineering) in the Overview section. # Webhook Integration - Developer Guide Source: https://docs.tryhamsa.com/developers/agent-guides/webhook-integration-guide Build robust webhook handlers to process Hamsa voice agent events # Webhook Integration for Developers Learn how to build production-ready webhook handlers to receive and process real-time call events from Hamsa voice agents. **Prerequisites:** * Webhook URL configured in dashboard ([Setup Guide](/agents/webhooks/introduction)) * Basic understanding of HTTP POST requests and JSON * Node.js, Python, or your preferred backend framework ## Understanding Webhook Data ### Custom Parameters (Echo Pattern) The most powerful feature of Hamsa webhooks is the **echo pattern**. All custom parameters you send during agent initiation are echoed back in the webhook response. **What You Send:** ```json theme={null} { "agentId": "agent-123-abc", "params": { "application_id": "12345", "user_id": "user-789", "session_id": "sess-abc-def", "candidate_name": "John Doe", "company_name": "Acme Corp" } } ``` **What You Receive in Webhook:** ```json theme={null} { "eventType": "call.ended", "data": { "data": { "outcomeResult": { "application_id": "12345", // ← Echoed back "user_id": "user-789", // ← Echoed back "session_id": "sess-abc-def", // ← Echoed back "candidate_name": "John Doe", // ← Echoed back "company_name": "Acme Corp", // ← Echoed back "expectedSalary": "80000", // ← New data from call "noticePeriod": "2 weeks" // ← New data from call } } } } ``` This pattern allows you to match webhook responses to your database records without maintaining state. ### Event Structure All webhook events follow this structure: ```typescript theme={null} { eventType: "call.started" | "call.answered" | "transcription.update" | "tool.executed" | "call.ended", callId: string, // Unique call identifier timestamp: string, // ISO 8601 timestamp projectId: string, // Your Hamsa project ID agentId: string, // Agent configuration ID agentName: string, // Agent name data: object // Event-specific data } ``` ### Call Ended Event (Most Important) The `call.ended` event contains complete conversation data: ```json theme={null} { "eventType": "call.ended", "callId": "call_uuid_12345", "timestamp": "2024-01-15T14:35:00.000Z", "data": { "timestamp": "2024-01-15T14:35:00.000Z", "data": { "conversationId": "conv-123-abc", "conversationRecording": "https://hamsa-recordings.s3.amazonaws.com/recording.mp3", "transcription": [ { "Agent": "Hello! How can I help you?" }, { "User": "I need assistance." } ], "outcomeResult": { // Your echoed params + collected data } } } } ``` ## Implementing Webhook Handlers ### Node.js/Express Implementation ```javascript theme={null} import express from 'express'; const app = express(); app.use(express.json()); // Middleware to verify Bearer token function verifyToken(req, res, next) { const authHeader = req.headers.authorization; const expectedToken = process.env.WEBHOOK_SECRET; if (authHeader !== expectedToken) { return res.status(401).json({ error: 'Unauthorized' }); } next(); } // Webhook endpoint app.post('/webhook', verifyToken, async (req, res) => { try { const event = req.body; console.log('Event:', event.eventType); console.log('Call ID:', event.callId); // Handle different event types switch (event.eventType) { case 'call.started': await handleCallStarted(event); break; case 'call.ended': await handleCallEnded(event); break; case 'transcription.update': await handleTranscription(event); break; } // Respond quickly res.status(200).json({ received: true }); } catch (error) { console.error('Webhook error:', error); // Still return 200 to avoid retries res.status(200).json({ received: true, processing_error: true }); } }); app.listen(3000, () => { console.log('Webhook server running on port 3000'); }); ``` ```javascript theme={null} async function handleCallEnded(event) { // Extract webhook data const { timestamp } = event.data; const { conversationId, conversationRecording, transcription, outcomeResult } = event.data.data; // Extract your custom identifiers (echoed back) const applicationId = outcomeResult.application_id; const userId = outcomeResult.user_id; const sessionId = outcomeResult.session_id; console.log('Identifiers:', { applicationId, userId, sessionId }); // Extract collected data (new from call) const expectedSalary = outcomeResult.expectedSalary; const noticePeriod = outcomeResult.noticePeriod; const numberOfSpeakers = outcomeResult.number_of_speakers; // Build transcript text const transcriptText = transcription .map(turn => { if (turn.Agent) return `Agent: ${turn.Agent}`; if (turn.User) return `User: ${turn.User}`; return ''; }) .filter(Boolean) .join('\n'); // Update your database await database.calls.update({ where: { applicationId }, data: { conversationId, recordingUrl: conversationRecording, transcript: transcriptText, expectedSalary, noticePeriod, numberOfSpeakers, completedAt: timestamp } }); } ``` ### Python/Flask Implementation ```python theme={null} from flask import Flask, request, jsonify import os app = Flask(__name__) def verify_token(): auth_header = request.headers.get('Authorization') expected_token = os.environ.get('WEBHOOK_SECRET') if auth_header != expected_token: return False return True @app.route('/webhook', methods=['POST']) def webhook(): # Verify authentication if not verify_token(): return jsonify({'error': 'Unauthorized'}), 401 try: event = request.get_json() print(f"Event: {event.get('eventType')}") print(f"Call ID: {event.get('callId')}") # Handle different event types event_type = event.get('eventType') if event_type == 'call.started': handle_call_started(event) elif event_type == 'call.ended': handle_call_ended(event) elif event_type == 'transcription.update': handle_transcription(event) return jsonify({'received': True}), 200 except Exception as e: print(f'Webhook error: {str(e)}') # Still return 200 return jsonify({ 'received': True, 'processing_error': True }), 200 if __name__ == '__main__': app.run(port=3000) ``` ```python theme={null} def handle_call_ended(event): # Extract webhook data data = event['data'] timestamp = data['timestamp'] conversation_data = data['data'] conversation_id = conversation_data['conversationId'] recording_url = conversation_data['conversationRecording'] transcription = conversation_data['transcription'] outcome_result = conversation_data['outcomeResult'] # Extract identifiers (echoed back) application_id = outcome_result.get('application_id') user_id = outcome_result.get('user_id') session_id = outcome_result.get('session_id') # Extract collected data expected_salary = outcome_result.get('expectedSalary') notice_period = outcome_result.get('noticePeriod') num_speakers = outcome_result.get('number_of_speakers') # Build transcript text transcript_parts = [] for turn in transcription: if 'Agent' in turn: transcript_parts.append(f"Agent: {turn['Agent']}") elif 'User' in turn: transcript_parts.append(f"User: {turn['User']}") transcript_text = '\n'.join(transcript_parts) # Update database update_database({ 'application_id': application_id, 'conversation_id': conversation_id, 'recording_url': recording_url, 'transcript': transcript_text, 'expected_salary': expected_salary, 'notice_period': notice_period, 'completed_at': timestamp }) ``` ## Advanced Topics ### Async Processing with Queues Always process webhooks asynchronously to avoid timeouts: ```javascript theme={null} const Queue = require('bull'); const eventQueue = new Queue('call-events', { redis: { host: '127.0.0.1', port: 6379 } }); // Webhook endpoint - respond immediately app.post('/webhook', verifyToken, async (req, res) => { const event = req.body; try { // Add to queue await eventQueue.add('process-event', event, { attempts: 3, backoff: { type: 'exponential', delay: 2000 } }); // Respond immediately res.status(200).json({ received: true }); } catch (error) { console.error('Queue error:', error); res.status(500).json({ error: 'Failed to queue event' }); } }); // Process events in background eventQueue.process('process-event', async (job) => { const event = job.data; if (event.eventType === 'call.ended') { await saveToDatabase(event); await sendNotifications(event); await updateAnalytics(event); } }); ``` ### Idempotency Prevent duplicate processing: ```javascript theme={null} const redis = require('redis').createClient(); async function isEventProcessed(event) { const eventKey = `webhook:${event.callId}:${event.eventType}:${event.timestamp}`; const exists = await redis.exists(eventKey); if (exists) { return true; // Already processed } // Mark as processed (expire after 24 hours) await redis.setex(eventKey, 86400, 'processed'); return false; } app.post('/webhook', async (req, res) => { const event = req.body; const alreadyProcessed = await isEventProcessed(event); if (alreadyProcessed) { console.log('Duplicate event, skipping'); return res.status(200).json({ received: true, duplicate: true }); } await processEvent(event); res.status(200).json({ received: true }); }); ``` ### Error Handling Comprehensive error handling: ```javascript theme={null} app.post('/webhook', async (req, res) => { try { // 1. Verify authentication if (!verifyToken(req)) { console.warn('Authentication failed:', { ip: req.ip }); return res.status(401).json({ error: 'Unauthorized' }); } // 2. Validate payload const event = req.body; if (!event.callId || !event.eventType) { console.error('Invalid payload'); return res.status(400).json({ error: 'Invalid payload' }); } // 3. Process with timeout const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Processing timeout')), 4000); }); await Promise.race([ processEvent(event), timeoutPromise ]); res.status(200).json({ received: true }); } catch (error) { console.error('Webhook error:', { error: error.message, stack: error.stack }); // Still return 200 res.status(200).json({ received: true, processing_error: true }); } }); ``` ## Common Use Cases ### CRM Integration ```javascript theme={null} async function syncToCRM(event) { if (event.eventType !== 'call.ended') return; const { outcomeResult, transcription } = event.data.data; // Build transcript const transcriptText = transcription .map(turn => Object.values(turn)[0]) .join('\n'); // Update CRM await crm.contacts.upsert({ where: { phone: outcomeResult.phone }, update: { lastCallDate: event.timestamp, lastCallNotes: transcriptText, intent: outcomeResult.intent, sentiment: outcomeResult.sentiment_score } }); // Create activity await crm.activities.create({ type: 'phone_call', contactPhone: outcomeResult.phone, subject: `AI Agent Call - ${outcomeResult.intent}`, description: transcriptText, recordingUrl: event.data.data.conversationRecording }); } ``` ### Notification System ```javascript theme={null} async function sendNotifications(event) { if (event.eventType !== 'call.ended') return; const { outcomeResult, callDuration } = event.data.data; // Urgent notification if (outcomeResult.priority === 'urgent' || !outcomeResult.resolved) { await slack.sendMessage({ channel: '#support-team', text: '🚨 Urgent call requires attention', blocks: [ { type: 'section', text: { type: 'mrkdwn', text: `*Call ID:* ${event.callId}\n*Duration:* ${callDuration}s` } }, { type: 'actions', elements: [ { type: 'button', text: { type: 'plain_text', text: 'View Details' }, url: `https://dashboard.example.com/calls/${event.callId}` } ] } ] }); } } ``` ## Troubleshooting ### Cannot Match Webhook to Record **Problem:** Missing application\_id in outcomeResult **Solution:** ```javascript theme={null} // ✅ Always include unique identifiers const config = { agentId: 'agent-123', params: { application_id: applicationId.toString(), user_id: userId.toString(), session_id: generateSessionId() } }; // In webhook - verify identifiers exist const applicationId = outcomeResult.application_id; if (!applicationId) { console.error('Missing identifier'); console.error('Full payload:', JSON.stringify(req.body, null, 2)); } ``` ### Missing or Null Fields **Problem:** Expected fields are null or undefined **Solution:** ```javascript theme={null} // Handle optional fields gracefully const expectedSalary = outcomeResult.expectedSalary ?? 'Not provided'; const noticePeriod = outcomeResult.noticePeriod || null; // Distinguish between null and undefined if (outcomeResult.expectedSalary === undefined) { console.log('Field not in agent configuration'); } else if (outcomeResult.expectedSalary === null) { console.log('User did not provide information'); } else { console.log('Value:', outcomeResult.expectedSalary); } ``` ### Duplicate Events **Problem:** Receiving same event multiple times **Solution:** Implement idempotency (see above section) ## Testing ### Local Testing with cURL ```bash theme={null} # Test with full payload curl -X POST https://your-endpoint.com/webhook \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your_secret_token" \ -d '{ "eventType": "call.ended", "callId": "test-123", "timestamp": "2024-01-15T14:35:00.000Z", "data": { "data": { "conversationId": "conv-test", "transcription": [], "outcomeResult": { "application_id": "12345" } } } }' ``` ### Monitoring ```javascript theme={null} const winston = require('winston'); const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'webhook-errors.log', level: 'error' }), new winston.transports.File({ filename: 'webhook-all.log' }) ] }); app.post('/webhook', async (req, res) => { const event = req.body; logger.info('Webhook received', { eventType: event.eventType, callId: event.callId, ip: req.ip }); try { await processEvent(event); logger.info('Processed successfully', { callId: event.callId }); } catch (error) { logger.error('Processing failed', { callId: event.callId, error: error.message, stack: error.stack }); } res.status(200).json({ received: true }); }); ``` ## Next Steps Set up webhook URLs in the dashboard Learn webhook concepts and patterns Configure what data to extract from calls Complete API documentation # API Integration Guide Source: https://docs.tryhamsa.com/developers/apis/api-integration Build integrations with the Hamsa API Learn how to integrate Hamsa voice agents into your applications using the API. ## What You'll Learn * Working with voice agents via API * Creating and updating agents programmatically * Managing agent configurations * Accessing call data and outcomes * Error handling and best practices ## Coming Soon This guide is being migrated from the [API Integration overview](/overview/guides/api-integration). Full content will include: * Complete API workflow examples * Authentication and security * Rate limiting and pagination * Code examples in multiple languages In the meantime, refer to the [API Reference](/api-reference/introduction) for complete endpoint documentation. # Genesys TTS Connector Integration Source: https://docs.tryhamsa.com/developers/apis/genesys-tts-connector Use Hamsa TTS voices in Genesys Cloud call and bot flows via the Genesys TTS Connector ## Overview The [Genesys TTS Connector](https://help.genesys.cloud/articles/activate-and-configure-the-genesys-tts-connector-integration/) lets Genesys Cloud organizations plug a third-party text-to-speech engine into their call and bot flows. Hamsa exposes two endpoints that speak the connector's protocol: 1. **List Voices** — the [Voices Catalog API](/developers/apis/voices-catalog), which Genesys fetches once at activation to build the voice selection list. 2. **Synthesize** — a dedicated streaming endpoint that takes text plus a voice id and streams back a WAV audio stream. You only ever send Hamsa a voice id: language and dialect are resolved from the voice itself, so there is no language mapping to configure. *** ## How It Works At activation, the connector calls the Voices Catalog endpoint and caches the list. Each voice's BCP-47 `language` tag places it under the matching flow language. Genesys substitutes the utterance and the selected voice id into the configured request template and POSTs it to the Synthesize endpoint. Hamsa validates the API key, resolves the voice (speaker, language, dialect), and streams an 8kHz WAV (linear PCM) audio stream back. Call flows start playing as soon as the first bytes arrive; bot flows buffer the full payload before playback. *** ## Synthesize Endpoint ``` POST https://api.tryhamsa.com/v1/realtime/connector/tts-stream ``` ### Authentication Send your Hamsa API key in the `Authorization` header: ``` Authorization: Token ``` Keep your Hamsa API key secret. Anyone who has it can make TTS requests that will be billed against your account. ### Request Body ```json theme={null} { "text": "", "voiceId": "", "sampleRate": "8k" } ``` | Field | Type | Required | Description | | ---------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------ | | `text` | string | Yes | Text to synthesise. Maximum 2000 characters | | `voiceId` | string (UUID) | Yes | A voice `id` from the [Voices Catalog](/developers/apis/voices-catalog). Determines speaker, language, and dialect | | `sampleRate` | string | No | `8k` (default) or `16k` | | `expressiveness` | number | No | 0–2, default 1 | | `speed` | number | No | 0.5–2, default 1 | ### Response On success the endpoint returns a **chunked WAV audio stream** (`Content-Type: audio/wav`): | Parameter | Value | | ----------- | --------------------------------------------------------------------------- | | HTTP Status | `200 OK` | | Sample Rate | 8 kHz (default) or 16 kHz | | Channels | Mono | | Encoding | 16-bit signed integers | | Byte Order | Little-endian | | Format | WAV container — a streaming RIFF header followed by uncompressed linear PCM | The stream is a valid WAV file: the RIFF header declares linear PCM (format 1) with the sizes set to the streaming convention (`0xFFFFFFFF`, i.e. "read until end of stream"). Genesys standardizes all provider audio to linear PCM at 8kHz; μ-law is not supported by the connector. ### Error Responses | Status | Meaning | | ------ | --------------------------------------------------------------------------------- | | `400` | Validation error — check required fields and that `text` is under 2000 characters | | `401` | Invalid or missing API key | | `402` | Insufficient wallet balance | | `404` | Voice not found or not available for this API key | | `429` | Rate limit exceeded | | `503` | TTS service temporarily unavailable | *** ## Setting Up in Genesys Cloud Prerequisite: the Genesys TTS Connector installed from AppFoundry (requires a BYOT-A subscription — see [Genesys's install guide](https://help.genesys.cloud/articles/install-the-genesys-tts-connector-integration/)). In Genesys Cloud go to **Admin → Integrations**, open your Genesys TTS Connector instance, and give it a recognizable name (e.g. `Hamsa TTS`). On the **Configuration** tab set: ``` List Voices URI: https://api.tryhamsa.com/v2/tts/voices/catalog Synthesize Text URI: https://api.tryhamsa.com/v1/realtime/connector/tts-stream Request Method: POST ``` To restrict the catalog to one dialect, bake the filter into the URI, e.g. `.../catalog?language=ar-SA`. Hamsa's catalog matches the connector's defaults (`voices` container; `id`, `name`, `language` attributes). Set the gender attribute to `gender` if you want gender shown in the voice list. In the **Advanced** tab, configure: ```json theme={null} { "synthesizeBody": { "text": "$text", "voiceId": "$voice", "sampleRate": "8k" } } ``` `$text` and `$voice` are substituted by Genesys on every request. No language mapping is needed — the voice id carries it. On the **Credentials** tab choose the **User Defined** type and add one field: | Field name | Value | | --------------- | ---------------------------- | | `Authorization` | `Token ` | Set the integration to **Active**, then select the Hamsa engine and a voice in Architect and use TTS playback to verify. Genesys caches the voice list at activation. If you add voices later (e.g. a new cloned voice), disable and re-enable the integration after at least 30 minutes so Genesys refreshes its cache. Genesys allows TTS requests up to 3,000 characters, while Hamsa's limit is 2,000 characters per request. Keep prompts under 2,000 characters to avoid validation errors. *** ## Example Request This is what Genesys sends to the Synthesize endpoint behind the scenes: ```bash theme={null} curl -X POST https://api.tryhamsa.com/v1/realtime/connector/tts-stream \ -H "Authorization: Token your-hamsa-api-key" \ -H "Content-Type: application/json" \ -d '{ "text": "مرحباً، كيف يمكنني مساعدتك اليوم؟", "voiceId": "6b52beba-b560-45d4-827b-49be73d50db7", "sampleRate": "8k" }' \ --output audio.wav ``` *** ## Support The List Voices endpoint reference Get help from our technical team # Quick Start Source: https://docs.tryhamsa.com/developers/apis/quick-start Complete guide to integrating with all Hamsa APIs - authentication, REST endpoints, real-time APIs, SDKs, and webhooks ## Overview This comprehensive guide covers everything you need to integrate with Hamsa's platform, including REST APIs, real-time WebSocket connections, the Voice Agents SDK, webhooks, and the tool system. Whether you're building a simple integration or a complex production system, this guide has you covered. **What This Guide Covers:** * Authentication methods for all API types * REST API integration patterns * Real-time Speech-to-Text and Text-to-Speech APIs * Voice Agents Web SDK * Webhook integration for event-driven architectures * Tool system for extending agent capabilities * Error handling and edge cases * Rate limiting and quota management * Production best practices *** ## Authentication Hamsa uses different authentication methods depending on the API type. Understanding these is crucial for successful integration. ### API Key Token Authentication Used for all REST API endpoints. ```bash theme={null} # Header format Authorization: Token # Example request curl -X GET https://api.tryhamsa.com/v1/voice-agents \ -H "Authorization: Token sk_live_abc123xyz789" \ -H "Content-Type: application/json" ``` **Security Best Practices:** * Never expose API keys in client-side code * Store keys in environment variables or secure vaults * Use separate keys for development and production * Rotate keys periodically * Use least-privilege keys when possible ### Bearer Token (JWT) Authentication Used for webhooks and tool authentication that the user adds to the system. ```bash theme={null} # Header format Authorization: Bearer # Example Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### Custom Header Authentication For tools and integrations that require custom authentication schemes. ```json theme={null} { "headers": [ { "name": "X-API-Key", "value": "your_custom_api_key" }, { "name": "X-Client-ID", "value": "client_123" } ] } ``` ### Getting Your API Key Sign up at [Hamsa Agents](https://agents.tryhamsa.com) Go to **Settings** → **API Keys** in the dashboard Click **Create API Key** and provide a descriptive name Copy the key immediately - it won't be shown again *** ## REST API Integration ### Base URL All REST API requests use the following base URL: ``` https://api.tryhamsa.com ``` ### API Versioning Hamsa provides multiple API versions. Use the version specified in the endpoint path: ``` /v1/voice-agents # Version 1 /v2/voice-agents # Version 2 (recommended for new integrations) ``` Some v1 endpoints are marked as **deprecated** in the API reference. For these endpoints, migrate to the v2 equivalent when available. Endpoints not marked as deprecated are fully supported. ### Request Format All requests should include: ```bash theme={null} Content-Type: application/json Authorization: Token ``` ### Response Format Almost all responses follow a consistent structure: **Success Response:** ```json theme={null} { "success": true, "data": { // Response data } } ``` **Error Response:** ```json theme={null} { "success": false, "error": { "code": "ERROR_CODE", "message": "Human-readable error message", "details": {} } } ``` ### Core API Endpoints #### Voice Agents | Method | Endpoint | Description | | ------- | ------------------------ | ----------------------------- | | `POST` | `/v2/voice-agents` | Create a new voice agent | | `GET` | `/v2/voice-agents` | List all voice agents | | `GET` | `/v2/voice-agents/{id}` | Get agent details | | `PATCH` | `/v2/voice-agents/{id}` | Update an agent | | `POST` | `/v1/voice-agents/clone` | Clone an existing agent | | `POST` | `/v1/voice-agents/call` | Initiate a call with an agent | **Create Agent Example:** ```javascript theme={null} const response = await fetch('https://api.tryhamsa.com/v2/voice-agents', { method: 'POST', headers: { 'Authorization': 'Token sk_live_abc123', 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Customer Support Agent', preamble: 'You are a helpful customer support agent...', greeting: 'Hello! How can I help you today?', language: 'en-US', voiceId: 'voice_abc123' }) }); const data = await response.json(); console.log('Created agent:', data.data.id); ``` #### Phone Numbers | Method | Endpoint | Description | | -------- | ------------------------------------ | -------------------------- | | `GET` | `/v1/voice-agents/phone-number` | List phone numbers | | `POST` | `/v1/voice-agents/phone-number` | Add a phone number | | `DELETE` | `/v1/voice-agents/phone-number` | Delete a phone number | | `POST` | `/v1/voice-agents/assign-number` | Assign number to agent | | `POST` | `/v1/voice-agents/unassign` | Unassign number from agent | | `POST` | `/v1/voice-agents/phone-number/call` | Make outbound call | #### Knowledge Base | Method | Endpoint | Description | | -------- | --------------------------------------------------- | ------------------------ | | `POST` | `/v1/voice-agents/knowledge-base` | Create knowledge item | | `GET` | `/v1/voice-agents/knowledge-base/list` | List all items | | `GET` | `/v1/voice-agents/knowledge-base/{id}` | Get item details | | `PATCH` | `/v1/voice-agents/knowledge-base/{id}` | Update item | | `DELETE` | `/v1/voice-agents/knowledge-base/{id}` | Delete item | | `POST` | `/v1/voice-agents/knowledge-base/{id}/url` | Add URL to item | | `POST` | `/v1/voice-agents/knowledge-base/toggle-activation` | Activate/deactivate item | **Knowledge Base Item Types:** * `TEXT` - Structured text content (50-5,000 characters) * `FILE` - PDF, DOCS, DOC, TXT, HTML, EPUB. * `URL` - Web pages (up to 100 URLs per item) #### Web Tools (Custom API Integration) | Method | Endpoint | Description | | ------- | --------------------------------------------- | ------------------- | | `POST` | `/v2/web-tool` | Create a web tool | | `GET` | `/v2/web-tool/list` | List all tools | | `PATCH` | `/v2/web-tool/{id}` | Update a tool | | `POST` | `/v1/voice-agents/web-tool/test-api-tool` | Test a tool | | `POST` | `/v1/voice-agents/web-tool/toggle-activation` | Activate/deactivate | #### Campaigns (Outbound Calling) | Method | Endpoint | Description | | ------- | ---------------------------------------- | -------------------- | | `POST` | `/v1/voice-agents/campaigns` | Create campaign | | `GET` | `/v1/voice-agents/campaigns` | List campaigns | | `GET` | `/v1/voice-agents/campaigns/{id}` | Get campaign details | | `PATCH` | `/v1/voice-agents/campaigns/{id}` | Update campaign | | `POST` | `/v1/voice-agents/campaigns/{id}/pause` | Pause campaign | | `POST` | `/v1/voice-agents/campaigns/{id}/resume` | Resume campaign | | `POST` | `/v1/voice-agents/campaigns/{id}/cancel` | Cancel campaign | | `POST` | `/v1/voice-agents/campaigns/{id}/retry` | Retry failed calls | #### Call History & Conversations | Method | Endpoint | Description | | ------ | ------------------------------------- | ---------------------------- | | `POST` | `/v1/voice-agents/conversations/list` | List calls with filters | | `GET` | `/v1/voice-agents/conversation/{id}` | Get call details | | `POST` | `/v1/voice-agents/join-call` | Join active call as listener | #### Media Processing (Jobs) | Method | Endpoint | Description | | ------ | ------------------------- | ------------------------- | | `POST` | `/v1/jobs/transcribe` | Transcribe audio/video | | `POST` | `/v1/jobs/text-to-speech` | Generate speech from text | | `POST` | `/v1/jobs/ai-content` | Generate AI Docs | | `GET` | `/v1/jobs` | Get job status | | `POST` | `/v1/jobs/all` | List all jobs | *** ## Real-Time APIs ### Real-Time Speech-to-Text (WebSocket) Connect to the real-time STT endpoint for live transcription: ```javascript theme={null} const ws = new WebSocket('wss://api.tryhamsa.com/v1/realtime/ws?api_key=YOUR_API_KEY'); ws.onopen = async () => { // Get audio from microphone const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mediaRecorder = new MediaRecorder(stream); const chunks = []; mediaRecorder.ondataavailable = (e) => chunks.push(e.data); mediaRecorder.onstop = async () => { const blob = new Blob(chunks); const buffer = await blob.arrayBuffer(); const base64 = btoa(String.fromCharCode(...new Uint8Array(buffer))); ws.send(JSON.stringify({ type: 'stt', payload: { audioBase64: base64, language: 'ar', isEosEnabled: true, eosThreshold: 0.3 } })); }; mediaRecorder.start(); setTimeout(() => mediaRecorder.stop(), 3000); // Record 3 seconds }; ws.onmessage = (event) => { if (typeof event.data === 'string') { try { const json = JSON.parse(event.data); if (json.type === 'error') { console.error('Error:', json.payload.message); } } catch { // Plain text transcription result console.log('Transcription:', event.data); } } }; ``` **Supported Audio Formats:** * `linear16` - 16-bit linear PCM at 16 kHz (default) or 8 kHz via `sampleRate: "8k"` * `mulaw` - 8-bit μ-law (always 8 kHz — cannot be combined with `sampleRate`) ### Real-Time Text-to-Speech (REST) **Standard TTS Request:** ```javascript theme={null} const response = await fetch('https://api.tryhamsa.com/v1/realtime/tts', { method: 'POST', headers: { 'Authorization': 'Token sk_live_abc123', 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Hello, how can I help you today?', speaker: 'Amjad', dialect: 'pls' }) }); const audioBlob = await response.blob(); const audioUrl = URL.createObjectURL(audioBlob); ``` **Streaming TTS Request:** If you are facing any issues while working with this endpoint, please refer to this [JSFiddle](https://jsfiddle.net/x9so4jyz/) which has a solution our team created as an example. ```javascript theme={null} const response = await fetch('https://api.tryhamsa.com/v1/realtime/tts-stream', { method: 'POST', headers: { 'Authorization': 'Token sk_live_abc123', 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'This is a longer text that will be streamed...', speaker: 'Amjad', dialect: 'pls', sampleRate: '16k' // or '8k' for telephony }) }); // Process streaming response const reader = response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; // Process audio chunk playAudioChunk(value); } ``` *** ## Voice Agents SDK Integration The Hamsa Voice Agents SDK provides a seamless way to embed voice interactions into web applications. ### Installation ```bash theme={null} npm install @hamsa-ai/voice-agents-sdk ``` Or via CDN: ```html theme={null} ``` ### Basic Usage ```javascript theme={null} import { HamsaVoiceAgent } from '@hamsa-ai/voice-agents-sdk'; // Initialize const agent = new HamsaVoiceAgent('YOUR_API_KEY'); // Start conversation await agent.start({ agentId: 'agent_abc123', params: { user_name: 'John Doe', user_id: 'user_123', session_id: 'session_abc' }, voiceEnablement: true, userId: 'user_123' }); // Event listeners agent.on('callStarted', ({ jobId }) => { console.log('Call started:', jobId); }); agent.on('transcriptionReceived', (text) => { console.log('User said:', text); }); agent.on('answerReceived', (text) => { console.log('Agent said:', text); }); agent.on('agentStateChanged', (state) => { // state: 'idle' | 'initializing' | 'listening' | 'thinking' | 'speaking' updateUI(state); }); agent.on('callEnded', () => { console.log('Call ended'); }); agent.on('error', (error) => { console.error('Error:', error); }); ``` ### Advanced Configuration ```javascript theme={null} await agent.start({ agentId: 'agent_abc123', voiceEnablement: true, // Custom parameters (echoed in webhooks) params: { application_id: '12345', user_id: 'user_789', session_id: 'sess_abc', custom_data: JSON.stringify({ key: 'value' }) }, // User tracking userId: 'user_789', // iOS optimization preferHeadphonesForIosDevices: true, // Platform-specific connection delays connectionDelay: { android: 3000, // Android needs longer delay ios: 500, default: 1000 }, // Audio capture for third-party services onAudioData: (audioData) => { thirdPartyWebSocket.send(audioData); }, // Client-side tools tools: [ { function_name: 'getUserInfo', description: 'Get user information', parameters: [ { name: 'userId', type: 'string', description: 'User ID' } ], required: ['userId'], fn: async (userId) => { return await fetchUserInfo(userId); } } ] }); ``` ### Audio Controls ```javascript theme={null} // Volume control agent.setVolume(0.8); const volume = agent.getOutputVolume(); // Microphone control agent.setMicMuted(true); agent.setMicMuted(false); const isMuted = agent.isMicMuted(); // Audio levels const inputLevel = agent.getInputVolume(); const outputLevel = agent.getOutputVolume(); // Frequency data for visualization const inputFreqData = agent.getInputByteFrequencyData(); const outputFreqData = agent.getOutputByteFrequencyData(); ``` ### Analytics & Monitoring ```javascript theme={null} // Get comprehensive analytics const analytics = agent.getCallAnalytics(); console.log(analytics); /* { connectionStats: { quality: 'good', connectionAttempts: 1, ... }, audioMetrics: { userAudioLevel: 0.8, agentAudioLevel: 0.3, ... }, performanceMetrics: { callDuration: 60000, responseTime: 1200, ... }, participants: [...], trackStats: { totalTracks: 2, activeTracks: 2, ... } } */ // Real-time connection quality agent.on('connectionQualityChanged', ({ quality, metrics }) => { if (quality === 'poor') { showNetworkWarning(); } }); // Custom events from agent agent.on('customEvent', (eventType, eventData, metadata) => { if (eventType === 'tool_execution') { console.log('Tool called:', eventData.toolName); } }); ``` ### Conversation Control ```javascript theme={null} // Pause conversation agent.pause(); // Resume conversation agent.resume(); // End conversation agent.end(); // Get current job ID const jobId = agent.getJobId(); ``` *** ## Webhook Integration Webhooks provide real-time notifications about call events, transcriptions, and outcomes. ### Webhook Events | Event | Description | When Triggered | | ---------------------- | ---------------- | ----------------- | | `call.started` | Call begins | Call initiated | | `call.answered` | Call connected | User picks up | | `transcription.update` | Real-time speech | User/agent speaks | | `tool.executed` | Tool called | Agent uses tool | | `call.ended` | Call completes | Call terminates | ### Setting Up Webhooks Create a publicly accessible HTTPS endpoint that accepts POST requests. Navigate to your agent's settings and add the webhook URL. Configure Bearer token authentication for security. Implement handlers for different event types. ### Webhook Configuration ```json theme={null} { "webhookUrl": "https://api.yourcompany.com/webhook/hamsa", "webhookAuth": { "authKey": "bearer", "authSecret": "Bearer your_secret_token_here" } } ``` ### Webhook Handler Implementation ```javascript theme={null} const express = require('express'); const app = express(); app.use(express.json()); // Verify Bearer token function verifyToken(req, res, next) { const authHeader = req.headers.authorization; const expectedToken = process.env.WEBHOOK_SECRET; if (authHeader !== expectedToken) { return res.status(401).json({ error: 'Unauthorized' }); } next(); } app.post('/webhook/hamsa', verifyToken, async (req, res) => { const event = req.body; try { switch (event.eventType) { case 'call.started': await handleCallStarted(event); break; case 'call.ended': await handleCallEnded(event); break; case 'transcription.update': await handleTranscription(event); break; case 'tool.executed': await handleToolExecution(event); break; } // Respond quickly to acknowledge receipt res.status(200).json({ received: true }); } catch (error) { console.error('Webhook error:', error); // Still return 200 to prevent retries res.status(200).json({ received: true, error: true }); } }); async function handleCallEnded(event) { const { conversationId, conversationRecording, transcription, outcomeResult } = event.data.data; // Extract echoed identifiers const applicationId = outcomeResult.application_id; const userId = outcomeResult.user_id; // Extract collected data const extractedData = { expectedSalary: outcomeResult.expectedSalary, noticePeriod: outcomeResult.noticePeriod, sentiment: outcomeResult.sentiment_score }; // Update your database await database.calls.update({ where: { applicationId }, data: { conversationId, recordingUrl: conversationRecording, transcript: transcription, ...extractedData, completedAt: new Date() } }); } ``` ```python theme={null} from flask import Flask, request, jsonify import os app = Flask(__name__) def verify_token(): auth_header = request.headers.get('Authorization') expected_token = os.environ.get('WEBHOOK_SECRET') return auth_header == expected_token @app.route('/webhook/hamsa', methods=['POST']) def webhook(): if not verify_token(): return jsonify({'error': 'Unauthorized'}), 401 event = request.get_json() try: event_type = event.get('eventType') if event_type == 'call.started': handle_call_started(event) elif event_type == 'call.ended': handle_call_ended(event) elif event_type == 'transcription.update': handle_transcription(event) elif event_type == 'tool.executed': handle_tool_execution(event) return jsonify({'received': True}), 200 except Exception as e: print(f'Webhook error: {e}') return jsonify({'received': True, 'error': True}), 200 def handle_call_ended(event): data = event['data']['data'] conversation_id = data['conversationId'] recording_url = data['conversationRecording'] transcription = data['transcription'] outcome = data['outcomeResult'] # Extract echoed identifiers application_id = outcome.get('application_id') user_id = outcome.get('user_id') # Update database update_database( application_id=application_id, conversation_id=conversation_id, recording_url=recording_url, transcription=transcription, outcome=outcome ) ``` ### Call Ended Payload Structure ```json theme={null} { "eventType": "call.ended", "callId": "call_uuid_12345", "timestamp": "2024-01-15T14:35:00.000Z", "projectId": "proj_abc123", "agentId": "agent_xyz789", "agentName": "Customer Support Agent", "data": { "timestamp": "2024-01-15T14:35:00.000Z", "data": { "conversationId": "conv-123-abc-456-def", "conversationRecording": "https://storage.tryhamsa.com/recordings/conv-123.mp3", "transcription": [ { "Agent": "Hello! How can I help you today?" }, { "User": "I need help with my order." }, { "Agent": "I'd be happy to help. What's your order number?" }, { "User": "It's ORD-12345." } ], "outcomeResult": { "application_id": "12345", "user_id": "user-789", "session_id": "sess-abc-def", "order_number": "ORD-12345", "issue_type": "order_inquiry", "resolved": true, "sentiment_score": 0.8 } } } } ``` ### Webhook Best Practices Return 200 OK within 5 seconds to avoid timeouts Queue events for async processing after acknowledging Use callId + eventType + timestamp to detect duplicates Use HTTPS and Bearer token authentication *** ## Error Handling ### HTTP Status Codes | Status | Meaning | Action | | ------ | ------------------- | ------------------------------ | | `200` | Success | Process response | | `400` | Bad Request | Check request parameters | | `401` | Unauthorized | Verify API key | | `403` | Forbidden | Check permissions | | `404` | Not Found | Verify resource ID | | `429` | Rate Limited | Wait and retry with backoff | | `500` | Server Error | Retry with exponential backoff | | `503` | Service Unavailable | Retry later | ### Common Error Codes Error codes are created by adding two pieces of numbers, first piece refers to the system part responsible for that error, and the second is the status code. Status code is always the last three numbers. | Code | Description | Resolution | | ------- | -------------------------- | --------------------------------- | | `10403` | Invalid or missing API key | Check API key format and validity | | `10404` | Resource doesn't exist | Verify resource ID | | `10400` | Request validation failed | Check request body format | | `10429` | Too many requests | Implement rate limiting | ### Error Handling Pattern ```javascript theme={null} async function apiRequest(endpoint, options = {}) { const maxRetries = 3; let lastError; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const response = await fetch(`https://api.tryhamsa.com${endpoint}`, { ...options, headers: { 'Authorization': `Token ${process.env.HAMSA_API_KEY}`, 'Content-Type': 'application/json', ...options.headers } }); const data = await response.json(); if (!response.ok) { // Handle specific error codes switch (response.status) { case 401: throw new AuthenticationError('Invalid API key'); case 404: throw new NotFoundError(data.error?.message || 'Resource not found'); case 429: // Rate limited - wait and retry const retryAfter = response.headers.get('Retry-After') || 60; await sleep(retryAfter * 1000); continue; case 500: case 503: // Server error - retry with backoff if (attempt < maxRetries) { await sleep(Math.pow(2, attempt) * 1000); continue; } throw new ServerError(data.error?.message || 'Server error'); default: throw new APIError(data.error?.message || 'API request failed', response.status); } } return data; } catch (error) { lastError = error; // Don't retry on authentication or validation errors if (error instanceof AuthenticationError || error instanceof ValidationError) { throw error; } // Retry on network errors if (attempt < maxRetries && error.name === 'NetworkError') { await sleep(Math.pow(2, attempt) * 1000); continue; } } } throw lastError; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } ``` *** ## Rate Limiting & Quotas ### Rate Limits | Endpoint Type | Limit | Window | | --------------------------------------- | ------------ | ---------- | | Standard APIs | 100 requests | Per minute | | Realtime APIs and Websocket Connections | 100 requests | Per minute | ### Rate Limit Headers ``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 1609459200 ``` ### Handling Rate Limits ```javascript theme={null} async function handleRateLimit(response) { if (response.status === 429) { const retryAfter = response.headers.get('Retry-After'); const resetTime = response.headers.get('X-RateLimit-Reset'); // Wait for the specified time const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : (parseInt(resetTime) - Date.now()); console.log(`Rate limited. Waiting ${waitTime}ms before retry...`); await sleep(waitTime); return true; // Indicates retry is needed } return false; } ``` ### Storage Quotas | Resource | Free Tier | Starter Tier | Creator Tier | Pro Tier | Business Tier | Enterprise | | -------------- | --------- | ------------ | ------------ | --------- | ------------- | ---------- | | Knowledge Base | 1 MB | 5 MB | 10 MB | 50 MB | 100 MB | 300 MB | | URLs per Item | 100 | 100 | 100 | 100 | 100 | 100 | | Agents | Unlimited | Unlimited | Unlimited | Unlimited | Unlimited | Unlimited | | Phone Numbers | Unlimited | Unlimited | Unlimited | Unlimited | Unlimited | Unlimited | ## Edge Cases & Best Practices ### Network Connectivity Issues ```javascript theme={null} // Implement connection health checks class ConnectionMonitor { constructor(sdk) { this.sdk = sdk; this.reconnectAttempts = 0; this.maxReconnectAttempts = 5; this.sdk.on('connectionQualityChanged', ({ quality }) => { if (quality === 'lost') { this.handleDisconnection(); } }); this.sdk.on('reconnecting', () => { console.log('Attempting to reconnect...'); }); this.sdk.on('reconnected', () => { this.reconnectAttempts = 0; console.log('Reconnected successfully'); }); } async handleDisconnection() { if (this.reconnectAttempts >= this.maxReconnectAttempts) { this.notifyUser('Connection lost. Please refresh the page.'); return; } this.reconnectAttempts++; const backoffTime = Math.pow(2, this.reconnectAttempts) * 1000; await sleep(backoffTime); try { await this.sdk.reconnect(); } catch (error) { this.handleDisconnection(); } } } ``` ### Handling Partial Responses ```javascript theme={null} // Handle partial webhook data function processWebhookPayload(payload) { const { outcomeResult } = payload.data?.data || {}; // Safely extract with defaults const data = { applicationId: outcomeResult?.application_id ?? null, userId: outcomeResult?.user_id ?? null, expectedSalary: outcomeResult?.expectedSalary ?? 'Not provided', noticePeriod: outcomeResult?.noticePeriod ?? 'Not provided', sentiment: outcomeResult?.sentiment_score ?? null }; // Log missing critical fields if (!data.applicationId) { console.warn('Missing application_id in webhook payload'); } return data; } ``` ### Concurrent Request Management ```javascript theme={null} // Use a request queue for concurrent operations class RequestQueue { constructor(maxConcurrent = 5) { this.maxConcurrent = maxConcurrent; this.running = 0; this.queue = []; } async add(requestFn) { return new Promise((resolve, reject) => { this.queue.push({ fn: requestFn, resolve, reject }); this.process(); }); } async process() { if (this.running >= this.maxConcurrent || this.queue.length === 0) { return; } this.running++; const { fn, resolve, reject } = this.queue.shift(); try { const result = await fn(); resolve(result); } catch (error) { reject(error); } finally { this.running--; this.process(); } } } // Usage const queue = new RequestQueue(3); const results = await Promise.all([ queue.add(() => fetchAgent(1)), queue.add(() => fetchAgent(2)), queue.add(() => fetchAgent(3)), queue.add(() => fetchAgent(4)), queue.add(() => fetchAgent(5)) ]); ``` ### Idempotency for Critical Operations ```javascript theme={null} // Idempotent operation wrapper async function idempotentOperation(operationId, operation) { const key = `operation:${operationId}`; // Check if already processed const cached = await redis.get(key); if (cached) { return JSON.parse(cached); } // Execute operation const result = await operation(); // Cache result with TTL await redis.setex(key, 86400, JSON.stringify(result)); return result; } // Usage await idempotentOperation( `create-agent-${sessionId}`, () => createVoiceAgent(agentConfig) ); ``` ### Graceful Degradation ```javascript theme={null} // Fallback strategy for service unavailability async function callWithFallback(primaryFn, fallbackFn, options = {}) { const { timeout = 5000, retries = 2 } = options; for (let i = 0; i <= retries; i++) { try { const result = await Promise.race([ primaryFn(), sleep(timeout).then(() => { throw new TimeoutError(); }) ]); return result; } catch (error) { if (i === retries) { console.warn('Primary service failed, using fallback'); return fallbackFn(); } await sleep(Math.pow(2, i) * 1000); } } } // Usage const result = await callWithFallback( () => fetchFromPrimaryAPI(), () => fetchFromCachedData(), { timeout: 3000, retries: 2 } ); ``` *** ## Production Deployment Checklist ### Security * [ ] API keys stored in secure vault/environment variables * [ ] HTTPS enabled for all endpoints * [ ] Bearer token authentication for webhooks * [ ] Input validation on all endpoints * [ ] Rate limiting implemented * [ ] Secrets rotated regularly * [ ] Audit logging enabled ### Reliability * [ ] Retry logic with exponential backoff * [ ] Circuit breaker pattern for external calls * [ ] Idempotency for critical operations * [ ] Dead letter queue for failed webhooks * [ ] Health check endpoints * [ ] Graceful shutdown handling ### Monitoring * [ ] Error tracking (Sentry, etc.) * [ ] API metrics (latency, error rates) * [ ] Webhook delivery monitoring * [ ] Call analytics dashboard * [ ] Alerting for anomalies * [ ] Log aggregation ### Performance * [ ] Connection pooling * [ ] Request queuing * [ ] Response caching where appropriate * [ ] Async processing for webhooks * [ ] Database query optimization * [ ] CDN for static assets *** ## Next Steps Complete API endpoint documentation Full SDK reference and examples Deep dive into webhook integration Integrate external APIs with agents *** ## Support Get help from our technical team Browse complete documentation **Document Version:** 1.0
**Last Updated:** 2026-01-07
**API Version:** v2.0.0
# UneeQ Digital Human Integration Source: https://docs.tryhamsa.com/developers/apis/uneeq-integration Use Hamsa TTS voices to power UneeQ digital human avatars via the custom voice endpoint ## Overview [UneeQ](https://www.uneeq.io) is a digital human platform that can use a custom voice service for text-to-speech synthesis. This guide explains how to connect UneeQ to Hamsa's real-time TTS engine so your digital human speaks with a Hamsa voice. Hamsa exposes a dedicated endpoint that speaks the UneeQ custom voice protocol — UneeQ calls it directly, passing your Hamsa API key and the desired voice preset, and receives a raw PCM audio stream in response. *** ## How It Works In your UneeQ experience settings, set the custom voice endpoint URL and provide your Hamsa API key. When the digital human needs to speak, UneeQ sends a POST request to your endpoint with the text and the voice preset name. Hamsa validates the API key, generates the audio using the requested voice, and streams back raw PCM audio. UneeQ receives the binary stream and drives the digital human's lip sync and speech in real time. *** ## Endpoint ``` POST https://api.tryhamsa.com/v1/realtime/uneeq/tts ``` ### Authentication Unlike other Hamsa endpoints, this one does **not** use an `Authorization` header. UneeQ sends the API key inside the JSON request body, so no extra headers are required on your side. Keep your Hamsa API key secret. Anyone who has it can make TTS requests that will be billed against your account. ### Request Body ```json theme={null} { "apiKey": "", "preset": "", "text": "" } ``` | Field | Type | Required | Description | | -------- | ------ | -------- | -------------------------------------------------------------- | | `apiKey` | string | Yes | Your Hamsa API key | | `preset` | string | Yes | Hamsa speaker name to use as the voice (e.g. `Amjad`, `Salma`) | | `text` | string | Yes | Text to synthesise. Maximum 2000 characters | ### Response On success the endpoint returns a **chunked binary stream** of raw PCM audio with the following properties: | Parameter | Value | | ------------ | --------------------------------------- | | HTTP Status | `200 OK` | | Content-Type | `application/octet-stream` | | Sample Rate | 16 kHz | | Channels | Mono | | Encoding | 16-bit signed integers | | Byte Order | Little-endian | | Format | Raw PCM — no WAV headers or compression | These audio specs match UneeQ's custom voice requirements exactly. No conversion is needed on your end. ### Error Responses | Status | Meaning | | ------ | ------------------------------------------------------------------------------------------------- | | `400` | Validation error — check that all required fields are present and `text` is under 2000 characters | | `401` | Invalid or missing API key | | `402` | Insufficient wallet balance | | `429` | Rate limit exceeded (100 requests/minute per API key) | | `503` | TTS service temporarily unavailable | *** ## Available Voices (Presets) Pass any Hamsa speaker name as the `preset` value. You can find the full list of available voices in the [Voice Library](https://media.tryhamsa.com/app/voices) on the dashboard. Some examples: | Preset | Description | | ------- | ---------------------------- | | `Amjad` | Male, Modern Standard Arabic | | `Salma` | Female, Egyptian dialect | | `Lyali` | Female, Levantine dialect | | `Jasem` | Male, Gulf dialect | The `preset` value maps directly to Hamsa's speaker names. The language is Arabic (`ar`) by default. If you need a different dialect, contact support to discuss configuration options. *** ## Setting Up in UneeQ Go to the UneeQ Creator and open the experience you want to configure. Go to **Settings → Voice → Custom Voice**. Enter: ``` https://api.tryhamsa.com/v1/realtime/uneeq/tts ``` Paste your Hamsa API key into the **API Key** field. UneeQ will include it as `apiKey` in every request body automatically. Enter the Hamsa speaker name (e.g. `Amjad`) in the **Preset / Voice** field. Save the configuration and use UneeQ's built-in voice preview to confirm the integration is working. *** ## Example Request This is what UneeQ sends to the endpoint behind the scenes: ```bash theme={null} curl -X POST https://api.tryhamsa.com/v1/realtime/uneeq/tts \ -H "Content-Type: application/json" \ -d '{ "apiKey": "your-hamsa-api-key", "preset": "Amjad", "text": "مرحباً، كيف يمكنني مساعدتك اليوم؟" }' \ --output audio.pcm ``` *** ## Support Get help from our technical team UneeQ's official custom voice integration guide # Using Custom Cloned Voices Source: https://docs.tryhamsa.com/developers/apis/use-cloned-voice-id-as-speaker Learn how to preload and use your custom cloned voices with Hamsa Real-Time APIs ## Overview When you create a custom cloned voice in Hamsa, you need to preload it into the system before using it with any real-time API endpoints. This one-time preload ensures your custom voice is ready and available, eliminating latency when making real-time TTS requests or WebSocket connections. **Why Preloading Matters:** Custom cloned voices require initialization in the system before they can be used. Without preloading, the first real-time request using your custom voice would experience significant latency as the system loads the voice model. *** ## When to Preload You should call the preload endpoint: * **Once when your application starts** - Preload during your app's initialization phase * **Before any real-time TTS or WebSocket usage** - Ensure the voice is ready before making real-time requests * **Only once per voice** - You don't need to preload the same voice multiple times **When is Preloading Required?** This preload step is required when using your custom cloned voice with: * Real-Time TTS REST API (`/v1/realtime/tts`) * Streaming TTS REST API (`/v1/realtime/tts-stream`) * Real-Time WebSocket connections **Not required for Voice Agents SDK** - The SDK handles voice preloading automatically. *** ## Preload Endpoint ### Endpoint Details | Property | Value | | ------------------ | ------------------------------------------------------- | | **Method** | `POST` | | **URL** | `https://api.tryhamsa.com/v2/tts/voices/custom/preload` | | **Authentication** | API Key (Token) | | **Content-Type** | `application/json` | ### Request Body ```json theme={null} { "voiceId": "your-custom-voice-id" } ``` | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------- | | `voiceId` | string | Yes | The unique identifier of your custom cloned voice | ### Response **Success Response (200):** ```json theme={null} { "success": true, "message": "Custom voice have been preloaded successfully", "data": [] } ``` **Error Responses:** | Status | Description | | ------ | ------------------------------------------------------ | | `400` | Bad request - Invalid voice ID format | | `401` | Unauthorized - Invalid or missing API key | | `404` | Voice not found - The specified voice ID doesn't exist | | `500` | Server error - Internal server error | *** ## Code Examples ### JavaScript/Node.js ```javascript theme={null} async function preloadCustomVoice(voiceId) { const response = await fetch('https://api.tryhamsa.com/v2/tts/voices/custom/preload', { method: 'POST', headers: { 'Authorization': 'Token YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ voiceId: voiceId }) }); const data = await response.json(); if (!response.ok) { throw new Error(`Failed to preload voice: ${data.message || response.statusText}`); } return data; } // Call this when your application starts async function initializeApp() { try { await preloadCustomVoice('c803658e-ccec-47e7-ad0f-1caf9ba4babb'); console.log('Custom voice preloaded successfully'); // Now you can safely use real-time TTS with this voice } catch (error) { console.error('Failed to preload voice:', error); } } initializeApp(); ``` ### Python ```python theme={null} import requests def preload_custom_voice(voice_id: str, api_key: str) -> dict: """Preload a custom cloned voice into the system.""" response = requests.post( 'https://api.tryhamsa.com/v2/tts/voices/custom/preload', headers={ 'Authorization': f'Token {api_key}', 'Content-Type': 'application/json' }, json={ 'voiceId': voice_id } ) response.raise_for_status() return response.json() # Call this when your application starts def initialize_app(): api_key = 'YOUR_API_KEY' voice_id = 'c803658e-ccec-47e7-ad0f-1caf9ba4babb' try: result = preload_custom_voice(voice_id, api_key) print('Custom voice preloaded successfully') # Now you can safely use real-time TTS with this voice except requests.exceptions.HTTPError as error: print(f'Failed to preload voice: {error}') if __name__ == '__main__': initialize_app() ``` ### cURL ```bash theme={null} curl -X POST https://api.tryhamsa.com/v2/tts/voices/custom/preload \ -H "Authorization: Token YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "voiceId": "c803658e-ccec-47e7-ad0f-1caf9ba4babb" }' ``` *** ## Integration Patterns ### App Startup Pattern The recommended approach is to preload your custom voice during application initialization, before making any real-time API calls: ```javascript theme={null} // app.js or index.js const CUSTOM_VOICE_ID = 'your-custom-voice-id'; const API_KEY = process.env.HAMSA_API_KEY; async function preloadVoice() { const response = await fetch('https://api.tryhamsa.com/v2/tts/voices/custom/preload', { method: 'POST', headers: { 'Authorization': `Token ${API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ voiceId: CUSTOM_VOICE_ID }) }); if (!response.ok) { console.warn('Voice preload failed, real-time TTS may have initial latency'); } } async function startApp() { // Preload custom voice at app startup await preloadVoice(); // Now you can use the custom voice with real-time TTS APIs // without experiencing initial latency } startApp(); ``` ### Multiple Voices Pattern If you have multiple custom voices, preload them all during startup: ```javascript theme={null} const CUSTOM_VOICES = [ 'voice-id-1', 'voice-id-2', 'voice-id-3' ]; async function preloadAllVoices() { const preloadPromises = CUSTOM_VOICES.map(voiceId => fetch('https://api.tryhamsa.com/v2/tts/voices/custom/preload', { method: 'POST', headers: { 'Authorization': `Token ${API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ voiceId }) }) ); const results = await Promise.allSettled(preloadPromises); results.forEach((result, index) => { if (result.status === 'fulfilled' && result.value.ok) { console.log(`Voice ${CUSTOM_VOICES[index]} preloaded`); } else { console.warn(`Failed to preload voice ${CUSTOM_VOICES[index]}`); } }); } ``` *** ## Troubleshooting ### Voice Not Found (404) If you receive a 404 error: * Verify the voice ID is correct * Ensure the custom voice was created successfully in your account * Check that you're using the correct API key associated with the voice ### Unauthorized (401) If you receive a 401 error: * Verify your API key is valid * Ensure the API key has permissions to access custom voices * Check the Authorization header format: `Token YOUR_API_KEY` ### Latency Still Present If you notice latency even after preloading: * Ensure the preload completed successfully before making real-time requests * Check that you're using the same voice ID in both preload and TTS requests * Verify the preload was called in the current session *** ## Related Resources Use your preloaded voice with the TTS endpoint Stream audio output with your custom voice Use custom voices with WebSocket connections # Voices Catalog API Source: https://docs.tryhamsa.com/developers/apis/voices-catalog List the Hamsa TTS voices available to your API key, with BCP-47 language tags — built for TTS connector integrations ## Overview The Voices Catalog is a read-only endpoint that returns every TTS voice your API key can use: Hamsa's published voice library plus any custom (cloned) voices owned by your account. Each voice carries a standard **BCP-47 language tag** (`ar-SA`, `ar-EG`, `en-US`) instead of Hamsa's internal dialect codes, so third-party platforms — such as the [Genesys TTS Connector](/developers/apis/genesys-tts-connector) — can consume it directly. The response is deliberately flat (`voices` at the top level, `id` / `name` / `language` / `gender` per voice) to match connector defaults with zero attribute remapping. *** ## Endpoint ``` GET https://api.tryhamsa.com/v2/tts/voices/catalog ``` ### Authentication Send your Hamsa API key in the `Authorization` header: ``` Authorization: Token ``` ### Query Parameters | Parameter | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `language` | string | No | Only return voices for this language or dialect. Accepts a BCP-47 tag (`ar-SA`) or an internal dialect code (`ksa`). Omit to get the full catalog | ### Response ```json theme={null} { "voices": [ { "id": "6b52beba-b560-45d4-827b-49be73d50db7", "name": "Amjad", "language": "ar-SA", "gender": "male" }, { "id": "4d8bb0fe-0a55-41b4-b367-33ba36dc0f67", "name": "Sarah", "language": "en-US", "gender": "female" } ] } ``` | Field | Type | Description | | ---------- | -------------- | ------------------------------------------------------------------------------------------------------------------------ | | `id` | string (UUID) | The voice id. Use it as `voiceId` in the [Connector TTS API](/developers/apis/genesys-tts-connector#synthesize-endpoint) | | `name` | string | Human-readable voice name | | `language` | string | BCP-47 language tag (see the table below) | | `gender` | string \| null | `male` or `female`; `null` when not tagged | The list includes your own cloned voices in addition to the public library. Cloned voices are visible only to the account that owns them. ### Language Tags | Dialect | Tag | | ---------------------- | ------- | | Saudi | `ar-SA` | | Gulf | `ar-SA` | | Egyptian | `ar-EG` | | Palestinian | `ar-PS` | | Syrian | `ar-SY` | | Iraqi | `ar-IQ` | | Jordanian | `ar-JO` | | Lebanese | `ar-LB` | | Emirati | `ar-AE` | | Bahraini | `ar-BH` | | Qatari | `ar-QA` | | Kuwaiti | `ar-KW` | | Omani | `ar-OM` | | Modern Standard Arabic | `ar` | | English | `en-US` | ### Error Responses | Status | Meaning | | ------ | -------------------------------------------------------- | | `400` | Validation error — `language` must be a non-empty string | | `401` | Invalid or missing API key | *** ## Example Requests Full catalog: ```bash theme={null} curl https://api.tryhamsa.com/v2/tts/voices/catalog \ -H "Authorization: Token your-hamsa-api-key" ``` Saudi voices only (both forms are equivalent): ```bash theme={null} curl "https://api.tryhamsa.com/v2/tts/voices/catalog?language=ar-SA" \ -H "Authorization: Token your-hamsa-api-key" curl "https://api.tryhamsa.com/v2/tts/voices/catalog?language=ksa" \ -H "Authorization: Token your-hamsa-api-key" ``` *** ## Related Use the catalog as the Genesys List Voices endpoint Browse and preview all voices in the dashboard # Hamsa Voice Agents Web SDK Source: https://docs.tryhamsa.com/developers/sdks/voice-agents-web-sdk JavaScript SDK for integrating voice agents into web applications Hamsa Voice Agents Web SDK is a JavaScript library for integrating voice agents from [Hamsa](https://agents.tryhamsa.com) into your web applications. It provides high-quality real-time audio communication for voice interactions in the browser. ## Installation Install the SDK via npm: ```bash theme={null} npm i @hamsa-ai/voice-agents-sdk ``` ## Usage ### Using via npm First, import the package in your code: ```javascript theme={null} import { HamsaVoiceAgent } from "@hamsa-ai/voice-agents-sdk"; ``` Initialize the SDK with your API key: ```javascript theme={null} const agent = new HamsaVoiceAgent(API_KEY); ``` ### Using via CDN Include the script from a CDN: ```html theme={null} ``` Then, you can initialize the agent like this: ```javascript theme={null} const agent = new HamsaVoiceAgent("YOUR_API_KEY"); agent.on("callStarted", ({ jobId }) => { console.log("Conversation has started! Job ID:", jobId); }); // Example: Start a call // agent.start({ agentId: 'YOUR_AGENT_ID' }); ``` Make sure to replace `LATEST_VERSION` with the actual latest version number. ## Start a Conversation with an Existing Agent Start a conversation with an existing agent by calling the "start" function. You can create and manage agents in our Dashboard or using our API (see: [Documentation Page](https://docs.tryhamsa.com/agents/dashboard/overview)): ```javascript theme={null} agent.start({ agentId: YOUR_AGENT_ID, params: { param1: "NAME", param2: "NAME2", }, voiceEnablement: true, userId: "user-123", // Optional user tracking preferHeadphonesForIosDevices: true, // iOS audio optimization connectionDelay: { android: 3000, // 3 second delay for Android ios: 0, default: 0, }, }); ``` When creating an agent, you can add parameters to your pre-defined values. For example, you can set your Greeting Message to: "Hello \{\{name}}, how can I help you today?" and pass the "name" as a parameter to use the correct name of the user. ## Pause/Resume a Conversation To pause the conversation, call the "pause" function. This will prevent the SDK from sending or receiving new data until you resume the conversation: ```javascript theme={null} agent.pause(); ``` To resume the conversation: ```javascript theme={null} agent.resume(); ``` ## End a Conversation To end a conversation, simply call the "end" function: ```javascript theme={null} agent.end(); ``` ## Advanced Audio Controls The SDK provides comprehensive audio control features for professional voice applications: ### Volume Management ```javascript theme={null} // Set agent voice volume (0.0 to 1.0) agent.setVolume(0.8); // Get current output volume const currentVolume = agent.getOutputVolume(); console.log(`Volume: ${Math.round(currentVolume * 100)}%`); // Get user microphone input level const inputLevel = agent.getInputVolume(); if (inputLevel > 0.1) { showUserSpeakingIndicator(); } ``` ### Microphone Control ```javascript theme={null} // Mute/unmute microphone agent.setMicMuted(true); // Mute agent.setMicMuted(false); // Unmute // Check mute status if (agent.isMicMuted()) { showUnmutePrompt(); } // Toggle microphone const currentMuted = agent.isMicMuted(); agent.setMicMuted(!currentMuted); // Listen for microphone events agent.on('micMuted', () => { document.getElementById('micButton').classList.add('muted'); }); agent.on('micUnmuted', () => { document.getElementById('micButton').classList.remove('muted'); }); ``` ### Audio Visualization Create real-time audio visualizers using frequency data: ```javascript theme={null} // Input visualizer (user's microphone) function createInputVisualizer() { const canvas = document.getElementById('inputVisualizer'); const ctx = canvas.getContext('2d'); function draw() { const frequencyData = agent.getInputByteFrequencyData(); ctx.clearRect(0, 0, canvas.width, canvas.height); const barWidth = canvas.width / frequencyData.length; for (let i = 0; i < frequencyData.length; i++) { const barHeight = (frequencyData[i] / 255) * canvas.height; ctx.fillStyle = `hsl(${i * 2}, 70%, 60%)`; ctx.fillRect(i * barWidth, canvas.height - barHeight, barWidth, barHeight); } requestAnimationFrame(draw); } draw(); } // Output visualizer (agent's voice) function createOutputVisualizer() { const canvas = document.getElementById('outputVisualizer'); const ctx = canvas.getContext('2d'); agent.on('speaking', () => { function draw() { const frequencyData = agent.getOutputByteFrequencyData(); if (frequencyData.length > 0) { ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw voice characteristics for (let i = 0; i < frequencyData.length; i++) { const barHeight = (frequencyData[i] / 255) * canvas.height; ctx.fillStyle = `hsl(${240 + i}, 70%, 60%)`; ctx.fillRect(i * 2, canvas.height - barHeight, 2, barHeight); } requestAnimationFrame(draw); } } draw(); }); } ``` ### Audio Capture Capture raw audio data from the agent or user for forwarding to third-party services, custom recording, or advanced audio processing. The SDK provides **three levels of API** for different use cases: #### Level 1: Simple Callback (Recommended for Most Users) The easiest way - just pass a callback to `start()`: ```javascript theme={null} // Dead simple - captures agent audio automatically await agent.start({ agentId: 'agent-123', voiceEnablement: true, onAudioData: (audioData) => { // Send to third-party service thirdPartyWebSocket.send(audioData); } }); ``` This automatically: * ✅ Captures **agent audio** only * ✅ Uses **opus-webm** format (efficient, compressed) * ✅ Delivers **100ms chunks** (good balance of latency/efficiency) * ✅ Starts immediately when call connects * ✅ No timing issues or event handling needed #### Level 2: Inline Configuration Need more control? Use `captureAudio` options: ```javascript theme={null} await agent.start({ agentId: 'agent-123', voiceEnablement: true, captureAudio: { source: 'both', // Capture both agent and user format: 'pcm-f32', // Raw PCM for processing bufferSize: 4096, onData: (audioData, metadata) => { if (metadata.source === 'agent') { processAgentAudio(audioData); } else { processUserAudio(audioData); } } } }); ``` #### Level 3: Dynamic Control For advanced users who need runtime control: ```javascript theme={null} // Start without capture await agent.start({ agentId: 'agent-123', voiceEnablement: true }); // Enable capture later, conditionally if (userWantsRecording) { agent.enableAudioCapture({ source: 'agent', format: 'opus-webm', chunkSize: 100, callback: (audioData, metadata) => { thirdPartyWebSocket.send(audioData); } }); } // Disable when done agent.disableAudioCapture(); ``` #### Audio Capture Formats The SDK supports three audio formats: 1. **`opus-webm`** (default, recommended) * Efficient Opus codec in WebM container * Small file size, good quality * Best for forwarding to services or recording * `audioData` is an `ArrayBuffer` 2. **`pcm-f32`** * Raw PCM audio as Float32Array * Values range from -1.0 to 1.0 * Best for audio analysis or DSP * `audioData` is a `Float32Array` 3. **`pcm-i16`** * Raw PCM audio as Int16Array * Values range from -32768 to 32767 * Best for compatibility with audio APIs * `audioData` is an `Int16Array` #### Common Use Cases **Forward agent audio to third-party service:** ```javascript theme={null} const socket = new WebSocket('wss://your-service.com/audio'); agent.enableAudioCapture({ source: 'agent', format: 'opus-webm', chunkSize: 100, callback: (audioData, metadata) => { socket.send(audioData); } }); ``` **Capture both agent and user audio:** ```javascript theme={null} agent.enableAudioCapture({ source: 'both', format: 'opus-webm', chunkSize: 100, callback: (audioData, metadata) => { if (metadata.source === 'agent') { processAgentAudio(audioData); } else { processUserAudio(audioData); } } }); ``` **Advanced: Custom audio analysis with PCM:** ```javascript theme={null} agent.enableAudioCapture({ source: 'agent', format: 'pcm-f32', bufferSize: 4096, callback: (audioData, metadata) => { const samples = audioData; // Float32Array // Calculate RMS volume let sum = 0; for (let i = 0; i < samples.length; i++) { sum += samples[i] * samples[i]; } const rms = Math.sqrt(sum / samples.length); console.log('Agent voice level:', rms); // Apply custom DSP, analyze frequencies, etc. customAudioProcessor.process(samples, metadata.sampleRate); } }); ``` **Real-time transcription:** ```javascript theme={null} const transcriptionWS = new WebSocket('wss://transcription-service.com'); agent.enableAudioCapture({ source: 'user', format: 'opus-webm', chunkSize: 50, // Lower latency callback: (audioData, metadata) => { transcriptionWS.send(JSON.stringify({ audio: Array.from(new Uint8Array(audioData)), timestamp: metadata.timestamp, participant: metadata.participant })); } }); ``` **TypeScript support:** ```typescript theme={null} import { AudioCaptureOptions, AudioCaptureMetadata } from '@hamsa-ai/voice-agents-sdk'; const options: AudioCaptureOptions = { source: 'agent', format: 'pcm-f32', bufferSize: 4096, callback: (audioData: Float32Array | Int16Array | ArrayBuffer, metadata: AudioCaptureMetadata) => { console.log('Audio captured:', { participant: metadata.participant, source: metadata.source, // 'agent' | 'user' trackId: metadata.trackId, timestamp: metadata.timestamp, sampleRate: metadata.sampleRate, // For PCM formats channels: metadata.channels, // For PCM formats format: metadata.format }); } }; agent.enableAudioCapture(options); ``` ## Advanced Configuration Options ### Platform-Specific Optimizations ```javascript theme={null} agent.start({ agentId: "your-agent-id", // Optimize audio for iOS devices preferHeadphonesForIosDevices: true, // Platform-specific delays to prevent audio cutoff connectionDelay: { android: 3000, // Android needs longer delay for audio mode switching ios: 500, // Shorter delay for iOS default: 1000 // Default for other platforms }, // Disable wake lock for battery optimization disableWakeLock: false, // User tracking userId: "customer-12345" }); ``` ## Job/Call ID Tracking Track and reference conversations using unique job IDs. The SDK provides two ways to access the job/call ID: ### Getting Job ID from Events (Recommended) The `callStarted` event includes the job ID in its data object: ```javascript theme={null} agent.on("callStarted", ({ jobId }) => { console.log("Call started with ID:", jobId); // Send to analytics service analytics.trackCall(jobId); // Store for later reference localStorage.setItem("lastCallId", jobId); }); ``` ### Getting Job ID with Getter Method Access the job ID anytime after the call has started: ```javascript theme={null} // Get current job ID const jobId = agent.getJobId(); if (jobId) { console.log("Current call ID:", jobId); } else { console.log("No active call"); } // Use in other events agent.on("transcriptionReceived", (text) => { const jobId = agent.getJobId(); saveTranscript(jobId, text); }); // Check completion status later agent.on("callEnded", async () => { const jobId = agent.getJobId(); if (jobId) { const details = await agent.getJobDetails(); console.log("Call completed:", details); } }); ``` ### TypeScript Support ```typescript theme={null} import { CallStartedData } from '@hamsa-ai/voice-agents-sdk'; // Event-based (with destructuring) agent.on("callStarted", ({ jobId }: CallStartedData) => { console.log("Job ID:", jobId); // string }); // Getter-based const jobId: string | null = agent.getJobId(); ``` ## Events During the conversation, the SDK emits events to update your application about the conversation status. ### Conversation Status Events ```javascript theme={null} agent.on("callStarted", ({ jobId }) => { console.log("Conversation has started with ID:", jobId); }); agent.on("callEnded", () => { console.log("Conversation has ended!"); }); agent.on("callPaused", () => { console.log("The conversation is paused"); }); agent.on("callResumed", () => { console.log("Conversation has resumed"); }); ``` ### Agent Status Events ```javascript theme={null} agent.on("speaking", () => { console.log("The agent is speaking"); }); agent.on("listening", () => { console.log("The agent is listening"); }); // Unified agent state change event agent.on("agentStateChanged", (state) => { console.log("Agent state:", state); // state can be: 'idle', 'initializing', 'listening', 'thinking', 'speaking' }); ``` ### Conversation Script Events ```javascript theme={null} agent.on("transcriptionReceived", (text) => { console.log("User speech transcription received", text); }); agent.on("answerReceived", (text) => { console.log("Agent answer received", text); }); ``` ### Error Events ```javascript theme={null} agent.on("closed", () => { console.log("Conversation was closed"); }); agent.on("error", (e) => { console.log("Error was received", e); }); ``` ### Advanced Analytics Events The SDK provides comprehensive analytics for monitoring call quality, performance, and custom agent events: ```javascript theme={null} // Real-time connection quality updates agent.on("connectionQualityChanged", ({ quality, participant, metrics }) => { console.log(`Connection quality: ${quality}`, metrics); }); // Periodic analytics updates (every second during calls) agent.on("analyticsUpdated", (analytics) => { console.log("Call analytics:", analytics); // Contains: connectionStats, audioMetrics, performanceMetrics, etc. }); // Participant events agent.on("participantConnected", (participant) => { console.log("Participant joined:", participant.identity); }); agent.on("participantDisconnected", (participant) => { console.log("Participant left:", participant.identity); }); // Track subscription events (audio/video streams) agent.on("trackSubscribed", ({ track, participant, trackStats }) => { console.log("New track:", track.kind, "from", participant); }); agent.on("trackUnsubscribed", ({ track, participant }) => { console.log("Track ended:", track.kind, "from", participant); }); // Connection state changes agent.on("reconnecting", () => { console.log("Attempting to reconnect..."); }); agent.on("reconnected", () => { console.log("Successfully reconnected"); }); // Custom events from agents agent.on("customEvent", (eventType, eventData, metadata) => { console.log(`Custom event: ${eventType}`, eventData); // Examples: flow_navigation, tool_execution, agent_state_change }); ``` ## Analytics & Monitoring The SDK provides comprehensive real-time analytics for monitoring call quality, performance metrics, and custom agent events. Access analytics data through both synchronous methods and event-driven updates. ### Analytics Architecture The SDK uses a clean modular design with four specialized components: * **Connection Management**: Handles room connections, participants, and network state * **Analytics Engine**: Processes WebRTC statistics and performance metrics * **Audio Management**: Manages audio tracks, volume control, and quality monitoring * **Tool Registry**: Handles RPC method registration and client-side tool execution Access analytics data through both synchronous methods and event-driven updates. ### Synchronous Analytics Methods Get real-time analytics data instantly for dashboards and monitoring: ```javascript theme={null} // Connection quality and network statistics const connectionStats = agent.getConnectionStats(); console.log(connectionStats); /* { quality: 'good', // Connection quality: excellent/good/poor/lost connectionAttempts: 1, // Total connection attempts reconnectionAttempts: 0, // Reconnection attempts connectionEstablishedTime: 250, // Time to establish connection (ms) isConnected: true // Current connection status } */ // Audio levels and quality metrics const audioLevels = agent.getAudioLevels(); console.log(audioLevels); /* { userAudioLevel: 0.8, // Current user audio level agentAudioLevel: 0.3, // Current agent audio level userSpeakingTime: 30000, // User speaking duration (ms) agentSpeakingTime: 20000, // Agent speaking duration (ms) audioDropouts: 0, // Audio interruption count echoCancellationActive: true,// Echo cancellation status volume: 1.0, // Current volume setting isPaused: false // Pause state } */ // Performance metrics const performance = agent.getPerformanceMetrics(); console.log(performance); /* { responseTime: 1200, // Total response time callDuration: 60000, // Current call duration (ms) connectionEstablishedTime: 250, // Time to establish connection reconnectionCount: 0, // Number of reconnections averageResponseTime: 1200 // Average response time } */ // Participant information const participants = agent.getParticipants(); console.log(participants); /* [ { identity: "agent", sid: "participant-sid", connectionTime: 1638360000000, metadata: "agent-metadata" } ] */ // Track statistics (audio/video streams) const trackStats = agent.getTrackStats(); console.log(trackStats); /* { totalTracks: 2, activeTracks: 2, audioElements: 1, trackDetails: [ ["track-id", { trackId: "track-id", kind: "audio", participant: "agent" }] ] } */ // Complete analytics snapshot const analytics = agent.getCallAnalytics(); console.log(analytics); /* { connectionStats: { quality: 'good', connectionAttempts: 1, isConnected: true, ... }, audioMetrics: { userAudioLevel: 0.8, agentAudioLevel: 0.3, ... }, performanceMetrics: { callDuration: 60000, responseTime: 1200, ... }, participants: [{ identity: 'agent', sid: 'participant-sid', ... }], trackStats: { totalTracks: 2, activeTracks: 2, ... }, callStats: { connectionAttempts: 1, packetsLost: 0, ... }, metadata: { callStartTime: 1638360000000, isConnected: true, isPaused: false, volume: 1.0 } } */ ``` ### Real-time Dashboard Example Build live monitoring dashboards using the analytics data: ```javascript theme={null} // Update dashboard every second const updateDashboard = () => { const stats = agent.getConnectionStats(); const audio = agent.getAudioLevels(); const performance = agent.getPerformanceMetrics(); // Update UI elements document.getElementById("quality").textContent = stats.quality; document.getElementById("attempts").textContent = stats.connectionAttempts; document.getElementById("duration").textContent = `${Math.floor( performance.callDuration / 1000 )}s`; document.getElementById("user-audio").style.width = `${ audio.userAudioLevel * 100 }%`; document.getElementById("agent-audio").style.width = `${ audio.agentAudioLevel * 100 }%`; }; // Start dashboard updates when call begins agent.on("callStarted", () => { const dashboardInterval = setInterval(updateDashboard, 1000); agent.on("callEnded", () => { clearInterval(dashboardInterval); }); }); ``` ### Custom Event Tracking Track custom events from your voice agents: ```javascript theme={null} agent.on("customEvent", (eventType, eventData, metadata) => { switch (eventType) { case "flow_navigation": console.log("Agent navigated:", eventData.from, "->", eventData.to); // Track conversation flow break; case "tool_execution": console.log( "Tool called:", eventData.toolName, "Result:", eventData.success ); // Monitor tool usage break; case "agent_state_change": console.log("Agent state:", eventData.state); // Track agent behavior break; case "user_intent_detected": console.log( "User intent:", eventData.intent, "Confidence:", eventData.confidence ); // Analyze user intent break; default: console.log("Custom event:", eventType, eventData); } }); ``` ## Configuration Options The SDK accepts optional configuration parameters: ```javascript theme={null} const agent = new HamsaVoiceAgent("YOUR_API_KEY", { API_URL: "https://api.tryhamsa.com", // API endpoint (default) }); ``` ## Client-Side Tools You can register client-side tools that the agent can call during conversations: ```javascript theme={null} const tools = [ { function_name: "getUserInfo", description: "Get user information", parameters: [ { name: "userId", type: "string", description: "User ID to look up", }, ], required: ["userId"], fn: async (userId) => { // Your tool implementation const userInfo = await fetchUserInfo(userId); return userInfo; }, }, ]; agent.start({ agentId: "YOUR_AGENT_ID", tools: tools, voiceEnablement: true, }); ``` ## Migration from Previous Versions If you're upgrading from a previous version, connection details are now automatically managed and no longer need to be configured. Check the changelog for detailed migration information. ## Browser Compatibility This SDK supports modern browsers with WebRTC capabilities: * Chrome 60+ * Firefox 60+ * Safari 12+ * Edge 79+ ## TypeScript Support The SDK includes comprehensive TypeScript definitions with detailed analytics interfaces: ```typescript theme={null} import { HamsaVoiceAgent, AgentState, AudioCaptureOptions, AudioCaptureMetadata, CallAnalyticsResult, CallStartedData, ParticipantData, CustomEventMetadata, } from "@hamsa-ai/voice-agents-sdk"; // All analytics methods return strongly typed data const agent = new HamsaVoiceAgent("API_KEY"); // TypeScript will provide full autocomplete and type checking for all methods const connectionStats = agent.getConnectionStats(); // ConnectionStatsResult | null const audioLevels = agent.getAudioLevels(); // AudioLevelsResult | null const performance = agent.getPerformanceMetrics(); // PerformanceMetricsResult | null const participants = agent.getParticipants(); // ParticipantData[] const trackStats = agent.getTrackStats(); // TrackStatsResult | null const analytics = agent.getCallAnalytics(); // CallAnalyticsResult | null // Job ID access const jobId = agent.getJobId(); // string | null // Advanced audio control methods const outputVolume = agent.getOutputVolume(); // number const inputVolume = agent.getInputVolume(); // number const isMuted = agent.isMicMuted(); // boolean const inputFreqData = agent.getInputByteFrequencyData(); // Uint8Array const outputFreqData = agent.getOutputByteFrequencyData(); // Uint8Array // Audio capture with full type safety agent.enableAudioCapture({ source: 'agent', format: 'opus-webm', chunkSize: 100, callback: (audioData: ArrayBuffer | Float32Array | Int16Array, metadata: AudioCaptureMetadata) => { // Full TypeScript autocomplete for metadata console.log(metadata.participant); // string console.log(metadata.source); // 'agent' | 'user' console.log(metadata.timestamp); // number console.log(metadata.trackId); // string console.log(metadata.sampleRate); // number | undefined } }); // Strongly typed start options with all advanced features await agent.start({ agentId: "agent-id", voiceEnablement: true, userId: "user-123", params: { userName: "John Doe", sessionId: "session-456" }, preferHeadphonesForIosDevices: true, connectionDelay: { android: 3000, ios: 500, default: 1000 }, disableWakeLock: false }); // Strongly typed event handlers agent.on("callStarted", ({ jobId }: CallStartedData) => { console.log("Job ID:", jobId); // string // Track conversation start }); agent.on("analyticsUpdated", (analytics: CallAnalyticsResult) => { console.log(analytics.connectionStats.quality); // string console.log(analytics.audioMetrics.userAudioLevel); // number console.log(analytics.performanceMetrics.callDuration); // number console.log(analytics.participants.length); // number }); // Audio control events agent.on("micMuted", () => { console.log("Microphone was muted"); }); agent.on("micUnmuted", () => { console.log("Microphone was unmuted"); }); // Agent state tracking with type safety agent.on("agentStateChanged", (state: AgentState) => { console.log("Agent state:", state); // 'idle' | 'initializing' | 'listening' | 'thinking' | 'speaking' // TypeScript provides autocomplete and type checking if (state === 'thinking') { showThinkingIndicator(); } }); // Strongly typed custom events agent.on( "customEvent", (eventType: string, eventData: any, metadata: CustomEventMetadata) => { console.log(metadata.timestamp); // number console.log(metadata.participant); // string } ); // Strongly typed participant events agent.on("participantConnected", (participant: ParticipantData) => { console.log(participant.identity); // string console.log(participant.connectionTime); // number }); ``` ## Use Cases ### Agent State UI Updates ```javascript theme={null} agent.on("agentStateChanged", (state) => { // Update UI based on agent state const statusElement = document.getElementById("agent-status"); switch (state) { case 'idle': statusElement.textContent = "Agent is idle"; statusElement.className = "status-idle"; break; case 'initializing': statusElement.textContent = "Agent is starting..."; statusElement.className = "status-initializing"; break; case 'listening': statusElement.textContent = "Agent is listening"; statusElement.className = "status-listening"; showMicrophoneAnimation(); break; case 'thinking': statusElement.textContent = "Agent is thinking..."; statusElement.className = "status-thinking"; showThinkingAnimation(); break; case 'speaking': statusElement.textContent = "Agent is speaking"; statusElement.className = "status-speaking"; showSpeakerAnimation(); break; } }); ``` ### Real-time Call Quality Monitoring ```javascript theme={null} agent.on("connectionQualityChanged", ({ quality, metrics }) => { if (quality === "poor") { showNetworkWarning(); logQualityIssue(metrics); } }); ``` ### Analytics Dashboard ```javascript theme={null} const analytics = agent.getCallAnalytics(); sendToAnalytics({ callDuration: analytics.callDuration, audioQuality: analytics.audioMetrics, participantCount: analytics.participants.length, performance: analytics.performanceMetrics, }); ``` ### Conversation Flow Analysis ```javascript theme={null} agent.on("customEvent", (eventType, data) => { if (eventType === "flow_navigation") { trackConversationFlow(data.from, data.to); optimizeAgentResponses(data); } }); ``` ## Dependencies * **livekit-client v2.15.4**: Real-time communication infrastructure * **events v3.3.0**: EventEmitter for browser compatibility The SDK uses LiveKit's native WebRTC capabilities for high-quality real-time audio communication and comprehensive analytics. # Creating Jobs Source: https://docs.tryhamsa.com/media/ai-docs/creating-jobs Step-by-step guide to creating AI Docs jobs from transcripts ## Overview Creating an AI Docs job involves selecting a completed transcript, choosing content templates, configuring settings, and generating structured written content. The system uses AI to transform transcript content into various formats like articles, social media posts, summaries, and FAQs. AI Docs generation requires a completed Speech to Text transcript. Ensure your transcript is finished before creating an AI Docs job. ## Prerequisites Before creating an AI Docs job: * **Active project**: Select your project * **Credit balance**: Ensure sufficient credits * **Content goals**: Know what type of content you want to generate ## Step-by-Step Process ### Step 1: Select Audio Input Choose your audio source for transcription: **Input Methods:** * **Upload File**: Upload audio/video file * **YouTube Link**: Paste YouTube video URL * **Record Audio**: Record directly in browser **Audio Requirements:** * Audio file format: MP3, WAV, WEBM, OGG * Maximum file size: 32MB * Minimum duration: 30 seconds * Maximum duration: 2 hours **Language Selection:** * Select language spoken in audio * Affects transcription accuracy * Used for content generation * Default: Arabic ### Step 2: Configure Job Details Enter information about your content: **Job Title:** * Descriptive title for the job * Used for organization * Maximum length: 255 characters * Example: "Product Launch Meeting - January 2024" **Recording Date:** * Date when audio was recorded * Optional but recommended * Helps with context * Calendar picker available **Description:** * Brief description of content * Helps AI understand context * Optional but recommended * Provides additional context **Participants:** * List of participants/speakers * Add one at a time * Press Space or Enter to add * Helps identify speakers **Audience:** * Target audience for content * Options: Public, Documentation, Internal Team * Affects content style * Required field **Tone:** * Desired writing tone * Options: Friendly, Professional, Informative, Casual, Formal, Persuasive, Authentic * Affects content style * Required field **Output Language:** * Language for generated content * Options: Arabic, English, Both (with primary) * May differ from audio language * Required field **Notes:** * Additional context or instructions * Optional field * Helps guide AI generation * Additional customization **AI Docs Text:** * Describe audience, participants, purpose * Optional but recommended * Provides context for generation * Helps tailor content ### Step 3: Select Content Templates Choose which content types to generate: **Available Templates:** * **Social Media Posts**: Posts for social platforms * **Web Article (SEO-Friendly)**: SEO-optimized articles * **Summary & Keywords**: Condensed summaries * **FAQ**: Frequently asked questions **Template Selection:** * Select one or more templates * Each generates different content * Can select multiple * All selected templates are generated **Template Categories:** * Social media content * Marketing content * Documentation * Educational content ### Step 4: Generate Content Create the AI Docs job: 1. **Review Settings** * Check all entered information * Verify template selection * Review job details * Ensure everything is correct 2. **Submit Job** * Click "Submit" or "Generate" button * Job is created * Processing begins * Status indicator shows progress 3. **Monitor Progress** * Watch status indicator * Processing typically takes minutes * Status updates in real-time * Completion notification 4. **Job Completion** * Status changes to "Completed" * Content is available * View generated content * Edit and customize as needed ## Input Method Details ### File Upload **Upload Process:** 1. Click "Upload Audio" option 2. Drag and drop file or click to browse 3. File uploads to server 4. Transcription begins automatically **File Requirements:** * Formats: MP3, WAV, M4A, WEBM * Max size: 32MB * Min duration: 30 seconds * Max duration: 2 hours ### YouTube Link **YouTube Process:** 1. Click "YouTube Link" option 2. Paste YouTube video URL 3. System validates URL 4. Audio extracted and transcribed **URL Requirements:** * Valid YouTube URL format * Public or accessible video * Video with audio track * Not a live stream (completed only) ### Record Audio **Recording Process:** 1. Click "Record Audio" option 2. Grant microphone permission 3. Click record button 4. Record audio directly **Recording Requirements:** * Microphone access permission * Minimum 30 seconds * Maximum 2 hours * Browser compatibility ## Job Details Configuration ### Required Fields **Job Title:** * Must not be empty * Descriptive name * Used for organization * Visible in jobs list **Audience:** * Must select one option * Affects content style * Important for generation * Cannot be skipped **Tone:** * Must select one option * Affects writing style * Important for generation * Required selection **Output Language:** * Must select language * Content generation language * May differ from audio * Required field ### Optional Fields **Recording Date:** * Optional but recommended * Provides context * Helps with dating content * Calendar picker **Description:** * Optional context * Helps AI understand * Additional information * Free text field **Participants:** * Optional list * Identifies speakers * Helps with context * Multiple participants **Notes:** * Optional instructions * Additional guidance * Custom instructions * Free text field **AI Docs Text:** * Optional description * Audience and purpose * Tailors content * Detailed context ## Template Selection ### Social Media Posts **Content Type:** * Posts optimized for social platforms * Platform-specific formatting * Engagement-focused * Shareable content **Use Cases:** * Social media campaigns * Platform posts * Engagement content * Marketing posts ### Web Article (SEO-Friendly) **Content Type:** * SEO-optimized articles * Web-ready format * Search engine friendly * Professional articles **Use Cases:** * Blog posts * Website articles * SEO content * Web publishing ### Summary & Keywords **Content Type:** * Condensed summaries * Key points extraction * Keyword identification * Quick overview **Use Cases:** * Executive summaries * Quick reviews * Key points * Overviews ### FAQ **Content Type:** * Frequently asked questions * Question-answer format * Organized structure * Comprehensive coverage **Use Cases:** * Support documentation * Help articles * Customer FAQs * Knowledge base ## Best Practices ### Audio Preparation **Quality:** * Clear audio recording * Minimal background noise * Adequate volume * Good microphone quality **Content:** * Well-structured conversation * Clear speaking * Organized discussion * Relevant content ### Job Details **Completeness:** * Fill all required fields * Provide optional context * Accurate information * Clear descriptions **Accuracy:** * Correct dates * Accurate participants * Realistic descriptions * Honest information ### Template Selection **Relevance:** * Choose relevant templates * Match content goals * Consider use cases * Select appropriate types **Quantity:** * Don't select unnecessary templates * Focus on needed types * Generate what you'll use * Avoid over-generation ## Troubleshooting ### Transcript Not Available **Issue:** Cannot select transcript **Solutions:** * Ensure transcript is completed * Check transcript status * Wait for completion * Verify transcript exists ### Job Creation Fails **Issue:** Cannot create job **Solutions:** * Check required fields * Verify audio/transcript * Check credit balance * Review error messages ### Processing Errors **Issue:** Job fails to process **Solutions:** * Check transcript quality * Verify settings * Review error details * Try again with corrections ## Next Steps After creating an AI Docs job: 1. **[Managing Content](./managing-content)** - Organize and manage your content 2. **[Overview](./overview)** - Learn about AI Docs features ## Related Documentation Organize and manage your content Learn about AI Docs features # Managing Content Source: https://docs.tryhamsa.com/media/ai-docs/managing-content Organize, edit, and manage your AI Docs jobs ## Overview The AI Docs management interface allows you to view, organize, edit, and manage all your generated content jobs. You can access content, make edits, export in various formats, and organize your content library. All your AI Docs jobs are saved and accessible. You can view, edit, regenerate, and export your generated content anytime. ## Content List View ### Viewing Jobs **Jobs List Display:** * All AI Docs jobs in a table/list * Job information visible * Status indicators * Quick actions available **Displayed Information:** * Job title * Status (Completed, Failed, Pending) * Creation date * Content type indicators * Actions menu ### Job Status **Status Types:** * **Pending**: Job queued for processing * **In Progress**: Content being generated * **Completed**: Content generated successfully * **Failed**: Generation encountered error **Status Indicators:** * Visual status badges * Color-coded indicators * Clear status labels * Real-time updates ## Content Operations ### View Content **View Job Details:** 1. Click on job in list 2. Content details page opens 3. View all generated content 4. Access editing tools **Content View Includes:** * All generated content types * Template-based sections * Editing interface * Export options ### Edit Content **Editing Capabilities:** * Edit generated text directly * Modify content sections * Customize formatting * Add or remove content **Editor Features:** * Rich text editing * Formatting options * Content organization * Save changes ### Export Content **Export Options:** * Export as PDF * Export as DOCX * Export as HTML * Export as TXT * Export as JSON **Export Process:** 1. Open content job 2. Click export button 3. Select format 4. Download file ### Delete Job **Delete Process:** 1. Click delete button 2. Confirm deletion 3. Job removed 4. Cannot be undone Deleting a job is permanent. Make sure you've exported any content you want to keep before deleting. ### Regenerate Content **Regenerate Options:** * Regenerate with same settings * Regenerate with new settings * Regenerate specific templates * Create variations **Regenerate Process:** 1. Open job details 2. Click regenerate 3. Adjust settings if needed 4. Generate new content ## Content Organization ### Search Jobs **Search Functionality:** * Search by job title * Search by content * Real-time search * Filter results ### Filter Jobs **Filter Options:** * Filter by status * Filter by date * Filter by content type * Combine filters ### Sort Jobs **Sort Options:** * Sort by date (newest/oldest) * Sort by title * Sort by status * Custom sorting ## Content Editing ### Text Editing **Editing Features:** * Inline text editing * Rich text formatting * Paragraph editing * Section editing **Formatting Options:** * Bold, italic, underline * Headings and paragraphs * Lists and bullets * Links and images ### Content Structure **Sections:** * Template-based sections * Organized content * Clear structure * Easy navigation **Organization:** * Headers and sections * Clear hierarchy * Logical flow * Professional layout ## Best Practices ### Content Management **Organization:** * Use descriptive titles * Organize by project * Review regularly * Archive old content **Quality Control:** * Review generated content * Edit for accuracy * Customize as needed * Maintain quality standards ### Content Editing **Review Process:** * Read through all content * Check for accuracy * Verify information * Edit as needed **Customization:** * Personalize content * Add brand voice * Customize formatting * Enhance content ## Troubleshooting ### Content Not Loading **Issue:** Content doesn't display **Solutions:** * Check job status * Refresh page * Verify job completed * Check network connection ### Editing Issues **Issue:** Cannot edit content **Solutions:** * Verify job is completed * Check permissions * Refresh page * Try again ### Export Problems **Issue:** Export fails **Solutions:** * Check file format * Verify content exists * Try different format * Check download permissions ## Next Steps * **[Creating Jobs](./creating-jobs)** - Learn how to create AI Docs jobs * **[Overview](./overview)** - Learn about AI Docs features ## Related Documentation Learn how to create AI Docs jobs Learn about AI Docs features # Overview Source: https://docs.tryhamsa.com/media/ai-docs/overview Generate structured written content from transcripts using AI-powered templates ## What is AI Docs? AI Docs generates structured written content based on completed transcripts. It uses AI-powered templates to transform audio transcriptions into various forms of written content, including social media posts, articles, summaries, FAQs, and more. **AI Docs enables you to:** * Generate multiple content types from transcripts * Use template-based content generation * Customize output with audience and tone settings * Export content in multiple formats * Create professional written content automatically ## Core Capabilities ### AI-Powered Text Generation Transform transcripts into structured content: * **Intelligent processing**: Advanced AI analyzes transcript content * **Context understanding**: Maintains context and meaning * **Multi-format output**: Generate various content types * **Template-based**: Use predefined templates for consistency * **Customizable**: Adjust audience, tone, and style ### Template-Based Content Creation Choose from predefined templates: * **Social media content**: Posts optimized for social platforms * **Marketing copy**: Advertising and promotional content * **Articles and blogs**: Full-length articles and blog posts * **Summaries**: Condensed versions of content * **FAQs**: Frequently asked questions * **Custom templates**: Create and use custom templates ## Content Generation Capabilities ### Input Selection * **Transcript selection**: Choose from completed STT transcripts * **Multiple sources**: Use transcripts from various sources * **Source validation**: Ensure transcript is completed * **Source metadata**: View transcript details and context ### Content Categories Generate content in various categories: * **Social Media** * Twitter/X posts * LinkedIn articles * Facebook posts * Instagram captions * **Marketing and Advertising** * Ad copy * Product descriptions * Promotional content * Email campaigns * **Articles and Blogs** * Blog posts * News articles * Feature articles * SEO-friendly content * **Business Content** * Meeting summaries * Business reports * Executive summaries * Documentation * **Educational Content** * Study guides * Course materials * Educational articles * Training content * **Technical Content** * Technical documentation * API documentation * Technical articles * Code explanations ### Generation Settings Customize content generation: * **Audience selection**: Target specific audiences * Public * Documentation * Internal Team * **Tone selection**: Control writing tone * Friendly * Professional * Informative * Casual * Formal * Persuasive * Authentic * **Language selection**: Choose output language * Arabic * English * Both (with primary selection) * **Additional context**: Provide extra information * Participants list * Recording date * Description * Notes and instructions ## Content Management Capabilities ### Job Management * **Job list**: View all AI Docs jobs * **Status tracking**: Monitor job progress * **Job details**: View generation settings and results * **Job operations**: Edit, regenerate, delete jobs ### Content Review * **Generated content**: View all generated content types * **Content editing**: Edit generated content directly * **Content comparison**: Compare different generations * **Content validation**: Review for accuracy and quality ### Content Operations * **Regenerate content**: Generate new content with different settings * **Copy content**: Copy content to clipboard * **Export content**: Download content in various formats * **Delete content**: Remove unwanted outputs ## Supported Content Categories ### Social Media Posts * **Platform-optimized**: Content tailored for specific platforms * **Character limits**: Respects platform character limits * **Hashtag suggestions**: Includes relevant hashtags * **Engagement optimization**: Designed for engagement ### Web Articles (SEO-Friendly) * **SEO optimization**: Search engine optimized content * **Keyword integration**: Natural keyword inclusion * **Structure**: Proper heading and paragraph structure * **Readability**: Optimized for reading experience ### Summaries and Keywords * **Key points extraction**: Identifies main points * **Keyword extraction**: Highlights important keywords * **Condensed format**: Shorter version of content * **Bullet points**: Easy-to-scan format ### FAQs * **Question generation**: Creates relevant questions * **Answer extraction**: Provides answers from transcript * **Organization**: Well-structured FAQ format * **Completeness**: Comprehensive coverage of topics ## Content Customization ### Header and Footer * **Custom headers**: Add company logos and titles * **Footer information**: Include contact details * **Branding**: Maintain brand consistency * **Visual customization**: Customize colors and images ### Formatting Options * **Text formatting**: Bold, italic, lists * **Structure**: Headings, paragraphs, sections * **Images**: Add and manage images * **Links**: Insert and manage links * **Colors**: Customize text and background colors ### Export Formats Export generated content: * **PDF**: Professional document format * **DOCX**: Microsoft Word format * **HTML**: Web-ready format * **TXT**: Plain text format * **JSON**: Structured data format ## Dependency Rules ### Transcript Requirement AI Docs generation requires: * **Completed transcript**: Must have a completed STT job * **Transcript validation**: System verifies transcript status * **Source linking**: Links AI Docs to source transcript * **Source access**: Access to original transcript ### Workflow Integration * **STT prerequisite**: Complete transcription first * **Seamless integration**: Direct link from STT to AI Docs * **Source preservation**: Maintains connection to source * **Regeneration support**: Regenerate from same source ## Job Status and Processing ### Processing States | Status | Description | Next Action | | ---------------- | ------------------------------- | ---------------------------- | | **PENDING** | Job is queued for processing | Wait for processing to start | | **IN\_PROGRESS** | Content is being generated | Wait for completion | | **COMPLETED** | Content generated successfully | View and edit content | | **FAILED** | Generation encountered an error | Review error and retry | ### Status Tracking * **Real-time updates**: See status changes in real-time * **Progress indicators**: Visual progress feedback * **Completion notifications**: Get notified when done * **Error messages**: Clear error descriptions ## Use Cases ### Content Marketing Create marketing content: * **Social media campaigns**: Generate social media posts * **Blog content**: Create blog posts from interviews * **Email campaigns**: Generate email content * **Ad copy**: Create advertising content ### Documentation Generate documentation: * **Meeting minutes**: Create structured meeting summaries * **Process documentation**: Document procedures and processes * **Training materials**: Create educational content * **Knowledge base**: Build knowledge base articles ### Content Repurposing Repurpose existing content: * **Multi-format output**: Same content in different formats * **Platform optimization**: Optimize for different platforms * **Audience adaptation**: Adapt for different audiences * **Tone variation**: Create different tone variations ### Research and Analysis Support research activities: * **Research summaries**: Summarize research interviews * **Key findings**: Extract key points * **FAQ generation**: Create FAQs from research * **Report generation**: Generate research reports ## Key Features ### Intelligent Content Generation * **Context awareness**: Understands transcript context * **Content quality**: High-quality, coherent content * **Template adherence**: Follows template structures * **Customization**: Adapts to settings and preferences ### Multi-Format Output * **Multiple templates**: Various content types from one transcript * **Format optimization**: Optimized for each format * **Export flexibility**: Multiple export options * **Content reuse**: Use content across platforms ### Professional Quality * **Grammar and style**: Professional writing quality * **Consistency**: Consistent tone and style * **Accuracy**: Maintains transcript accuracy * **Completeness**: Comprehensive content coverage ## Getting Started 1. **Complete a Transcript** * Ensure you have a completed STT job * Verify transcript is ready for processing 2. **Create AI Docs Job** * Select the transcript source * Choose content category and template * Configure audience, tone, and language * Add additional context if needed 3. **Review Generated Content** * View all generated content types * Edit and refine content * Customize formatting and styling 4. **Export and Use** * Export in your preferred format * Use content across platforms * Share with your team ## What's Next? * **[Creating AI Docs Jobs](./creating-jobs)** - Learn how to create AI Docs jobs * **[Managing Content](./managing-content)** - Organize and manage generated content # Media Platform Introduction Source: https://docs.tryhamsa.com/media/introduction Comprehensive media processing platform for transcription, voice synthesis, and AI content generation # Welcome to Hamsa Media Platform Hamsa Media is a comprehensive platform for processing audio and video content, generating natural speech, and creating AI-powered written content. It provides powerful tools for transcription, voice synthesis, content generation, and voice management in one integrated workspace. ## Overview The Media Platform enables you to: * **Transcribe** audio and video files into editable text with speaker separation * **Generate** natural-sounding speech from text using customizable voices * **Create** AI-powered written content from transcripts * **Manage** custom voices and voice libraries ## Key Features ### Speech to Text (STT) Convert audio and video content into structured, editable text transcripts with automatic speaker detection, time-based segmentation, and comprehensive export options. **[→ Learn More: Speech to Text](./speech-to-text/overview)** ### Text to Speech (TTS) Transform written content into human-like audio using configurable voice models with advanced controls for speed, expressiveness, and voice selection. **[→ Learn More: Text to Speech](./text-to-speech/overview)** ### AI Docs Generate structured written content from completed transcripts using AI-powered templates for social media, marketing, articles, and more. **[→ Learn More: AI Docs](./ai-docs/overview)** ### Voices Discover, manage, and create custom voices for use across the platform. Browse system voices, filter by language and style, and create custom cloned voices. **[→ Learn More: Voices](../overview/features/voices)** ## End-to-End Workflow Hamsa Media supports a complete content processing workflow: 1. **Upload or record** audio/video files 2. **Transcribe** content using Speech to Text 3. **Edit and manage** transcripts with speaker separation 4. **Generate** AI content or speech audio 5. **Select or create** voices as needed 6. **Download or reuse** generated outputs ## Export and Download * Multiple export formats (DOCX, PDF, TXT, JSON, HTML, SRT) * Audio downloads (WAV) ## Choose Your Starting Point * Use Speech to Text if you have audio or video you want to turn into text. * Choose Text to Speech when you need to create audio from written content. * Start with AI docs if you already have transcripts and want to generate or improve content using AI ## What's Next? * **[Speech to Text Overview](./speech-to-text/overview)** - Learn about transcription features * **[Text to Speech Overview](./text-to-speech/overview)** - Discover voice synthesis capabilities * **[AI Docs Overview](./ai-docs/overview)** - Explore content generation features * **[Quick Start Guide](/overview/quickstart)** - Get started with Hamsa Platform # Creating Transcriptions Source: https://docs.tryhamsa.com/media/speech-to-text/creating-transcriptions Step-by-step guide to creating transcription jobs from files, YouTube links, or recordings ## Overview Speech to Text supports three methods for creating transcription jobs: * **File Upload**: Upload audio or video files from your device * **YouTube Link**: Transcribe videos directly from YouTube * **Live Recording**: Record audio directly in your browser Supported file types for upload Supported file types for upload All transcription jobs are processed asynchronously. Processing time depends on file length, typically 1-5 minutes for most files. You can monitor job status in real-time. ## Creating File Upload Transcriptions File upload allows you to transcribe audio and video files stored on your device. ### When to Use File Upload File upload is ideal for: * Pre-recorded audio files * Video files with audio tracks * Archived recordings * Files from your computer or mobile device ### Supported File Formats | Format | Extension | Max Size | Recommended | | ------------ | --------- | -------- | ------------------ | | Audio - MP3 | `.mp3` | 200 MB | Best compatibility | | Audio - WAV | `.wav` | 200 MB | High quality | | Audio - WEBM | `.webm` | 200 MB | High quality | | Audio - OGG | `.ogg` | 200 MB | High quality | | Video - MP4 | `.mp4` | 200 MB | Most common | | Video - MOV | `.mov` | 200 MB | Apple format | ### Requirements | Field | Requirement | Validation | | ------------ | ----------- | ----------------------------------- | | **File** | Required | one file max size 200 MB | | **Title** | Required | Auto-filled from filename, editable | | **Language** | Required | Select from language dropdown | ### Step-by-Step Process 1. **Navigate to Speech to Text** * Go to the Speech to Text section in your dashboard * Click the **"Upload"** button in the action buttons area Navigate to Speech to Text section Navigate to Speech to Text section 2. **Open Upload Modal** * The "Transcribe Files" modal opens * You'll see a drag-and-drop area Open upload modal Open upload modal 3. **Select File** * **Drag and Drop**: Drag a file from your file explorer into the upload area * **Click to Browse**: Click the upload area to open file picker * **Single File**: Select one file at a time * File appears below the upload area 4. **File Validation** * System validates file format immediately * Invalid files are rejected with error message * File size is checked (must be under 200MB) 5. **Enter Job Details** * **Title**: Auto-filled from filename, can be edited * Example: "Meeting Recording - January 15" * Example: "Customer Interview - Product Feedback" * **Primary Language**: Select the language spoken in the audio * Default: Arabic * Options: Arabic, English * Title field updates automatically when file is selected 6. **Review File** * Check file name is correct * Verify file details are accurate * Remove file if needed (click X button) 7. **Submit for Processing** * Click **"Upload"** button * File uploads to the server * Transcription job is created * You're redirected to the jobs list Once uploaded, file cannot be modified. Ensure you upload the correct file and enter accurate metadata before submitting. ### File Upload Best Practices **File Preparation:** * Ensure files are not corrupted or password-protected * Verify audio quality is sufficient for transcription * Use clear, descriptive filenames before uploading * Compress very large files if possible (while maintaining quality) **Content Quality:** * Clear audio with minimal background noise * Single language per file (multi-language may reduce accuracy) * Adequate volume levels * Minimal echo or distortion **Example Filenames:** ``` Good: "Team_Meeting_2024_01_15.mp3" Good: "Customer_Interview_Product_X.wav" Bad: "recording.mp3" Bad: "file_final_final_v2.mp4" ``` ### File Upload Limitations * **Maximum file size**: 200MB per file * **Maximum files per upload**: 1 file * **Processing time**: 1-5 minutes per file (depends on length) * **File format**: Must match supported formats exactly ### Upload Process Details After clicking "Upload", the system: 1. **Upload Phase**: File uploads to secure storage * Progress indicator shows upload status * Upload time depends on file size and connection speed 2. **Validation Phase**: System validates files * Format verification * Size verification * Audio track detection (for video files) 3. **Job Creation**: Transcription job created * Job ID assigned * Status set to "PENDING" * Job appears in jobs list 4. **Processing Starts**: Transcription begins automatically * Status changes to "IN\_PROGRESS" * Real-time status updates available * Completion notification when done Each uploaded file creates a separate transcription job. You can upload one file at a time to create transcription jobs. ## Creating YouTube Link Transcriptions YouTube link transcription allows you to transcribe videos directly from YouTube without downloading them. ### When to Use YouTube Links YouTube links are ideal for: * Public YouTube videos * Video content you don't have downloaded * Online video transcription * Quick transcription without file handling * Videos already on YouTube ### Requirements | Field | Requirement | Validation | | --------------- | ----------- | -------------------------------------- | | **YouTube URL** | Required | Valid YouTube video URL | | **Title** | Required | Auto-filled from video title, editable | | **Language** | Required | Select from language dropdown | ### URL Validation Rules **Required Format:** * Must be a valid YouTube URL * Formats supported: * `https://www.youtube.com/watch?v=VIDEO_ID` * `https://youtu.be/VIDEO_ID` * `https://youtube.com/watch?v=VIDEO_ID` **Not Supported:** * Private or unlisted videos (unless you have access) * Videos with age restrictions * Live streams (completed streams only) * Videos longer than 2 hours (processing limitations) ### Step-by-Step Process 1. **Navigate to Speech to Text** * Go to the Speech to Text section * Click the **"YouTube"** button in the action buttons area Navigate to Speech to Text section and click YouTube button Navigate to Speech to Text section and click YouTube button 2. **Open YouTube Modal** * The "Transcribe YouTube Video" modal opens * You'll see URL input field Transcribe YouTube video modal Transcribe YouTube video modal 3. **Enter YouTube URL** * Paste or type the YouTube video URL * URL validation happens in real-time * Valid URLs show green checkmark * Invalid URLs show error message 4. **URL Validation** * System validates URL format * Checks if video is accessible * Retrieves video metadata * Status indicator shows validation progress 5. **Video Information** * Video title is retrieved automatically * Title field is auto-filled * You can edit the title if needed 6. **Enter Job Details** * **Title**: Auto-filled from video title, can be edited * Example: "Product Demo Video - January 2024" * Example: "Tutorial: Getting Started Guide" * **Primary Language**: Select the language spoken in the video * Default: Arabic * Options: Arabic, English 7. **Submit for Processing** * Click **"Submit"** button * System extracts audio from video * Transcription job is created * You're redirected to the jobs list YouTube videos must be publicly accessible. Private or unlisted videos may fail if you don't have proper access permissions. ### YouTube URL Examples **Standard YouTube URL:** ``` https://www.youtube.com/watch?v=dQw4w9WgXcQ ``` **Short YouTube URL:** ``` https://youtu.be/dQw4w9WgXcQ ``` **With Timestamp:** ``` https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=120s (Note: Timestamp is ignored, entire video is transcribed) ``` ### YouTube Processing Details The system: 1. **Video Access**: Validates video is accessible 2. **Audio Extraction**: Downloads and extracts audio track 3. **Job Creation**: Creates transcription job 4. **Processing**: Transcribes extracted audio 5. **Completion**: Video title and metadata preserved YouTube transcription uses the same processing pipeline as file uploads. The only difference is the source of the audio file. ## Creating Live Recording Transcriptions Live recording allows you to record audio directly in your browser and transcribe it immediately. ### When to Use Live Recording Live recording is ideal for: * Quick voice notes * Immediate transcription needs * Testing and practice * Interviews or conversations * Real-time recording scenarios ### Requirements | Field | Requirement | Notes | | --------------------- | ----------- | ----------------------------- | | **Recording** | Required | Minimum 30 seconds | | **Title** | Required | Enter descriptive title | | **Language** | Required | Select from language dropdown | | **Microphone Access** | Required | Browser permission needed | ### Browser Compatibility **Supported Browsers:** * Chrome (recommended) * Firefox * Edge * Safari (with limitations) **Requirements:** * Microphone access permission * HTTPS connection (required for microphone access) * Modern browser with MediaRecorder API support ### Step-by-Step Process 1. **Navigate to Speech to Text** * Go to the Speech to Text section * Click the **"Record"** button in the action buttons area Navigate to Speech to Text section and click Record button Navigate to Speech to Text section and click Record button 2. **Open Record Modal** * The "Record Audio" modal opens * You'll see recording interface Record audio modal Record audio modal 3. **Grant Microphone Permission** * Browser requests microphone access * Click **"Allow"** to grant permission * Permission is remembered for future recordings 4. **Prepare for Recording** * Ensure microphone is working * Test audio levels (visual indicator) * Find quiet environment if possible * Position yourself near microphone 5. **Start Recording** * Click the **"Record"** button (microphone icon) * Recording starts immediately * Timer shows recording duration * Visual indicator shows recording is active 6. **During Recording** * **Pause**: Click pause button to temporarily stop * **Resume**: Click resume to continue recording * **Stop**: Click stop when finished * Minimum recording: 30 seconds * Maximum recommended: 2 hours During recording interface showing pause, stop, and cancel buttons During recording interface showing pause, stop, and cancel buttons 7. **Stop Recording** * Click **"Stop"** button * Recording is finalized * Audio preview is available * You can review before submitting 8. **Review Recording** * Playback available to review * Check audio quality * Delete and re-record if needed * Recording duration displayed Review recording interface with playback, delete options, and job details Review recording interface with playback, delete options, and job details 9. **Enter Job Details** * **Title**: Enter descriptive title * Example: "Voice Note - Project Ideas" * Example: "Interview Recording - Candidate Name" * **Primary Language**: Select language spoken * Default: Arabic * Options: Arabic, English 10. **Submit for Processing** * Click **"Submit"** button * Recording is saved and uploaded * Transcription job is created * You're redirected to the jobs list Browser-based recording quality depends on your microphone and environment. For best results, use a good quality microphone in a quiet environment. ### Recording Controls **Record Button:** * Starts recording session * Changes to pause/stop when active * Visual feedback (pulsing animation) **Pause/Resume:** * Temporarily stops recording * Resumes from same point * Timer pauses during pause **Stop Button:** * Finalizes recording * Prepares audio for submission * Cannot resume after stopping **Delete Recording:** * Removes current recording * Returns to start state * Must re-record to continue ### Recording Best Practices **Environment:** * Use quiet room with minimal background noise * Close windows to reduce external noise * Turn off notifications on devices * Use headset microphone if available **Speaking:** * Speak clearly and at moderate pace * Maintain consistent distance from microphone * Avoid covering microphone * Pause naturally between thoughts **Technical:** * Test microphone before important recordings * Check browser permissions * Ensure stable internet connection * Close unnecessary browser tabs ### Recording Limitations * **Minimum duration**: 30 seconds * **Maximum duration**: 2 hours (recommended) * **Quality**: Depends on microphone and browser * **Format**: Browser-encoded audio format * **Network**: Requires stable connection for upload ## Language Selection All transcription methods require selecting the primary language. ### Available Languages * **Arabic** (default) * **English** ### Language Selection Guidelines **Single Language:** * Select the primary language spoken * Best accuracy when one language is dominant * Mixed language may reduce accuracy **Language Detection:** * System attempts automatic detection * Manual selection recommended for accuracy * Incorrect language selection affects quality Selecting the correct language significantly improves transcription accuracy. Choose the language that represents the majority of spoken content. ## Job Status and Processing After creating a transcription job, it goes through these states: ### Processing States | Status | Description | Duration | Actions Available | | ------------- | ------------------------- | --------------------- | -------------------------- | | **PENDING** | Transcription in progress | 1-5 minutes (typical) | Wait, view progress | | **COMPLETED** | Transcription finished | - | View, edit, export, delete | | **FAILED** | Processing error occurred | - | View error, delete, retry | ### Monitoring Job Status **Jobs List:** * View all transcription jobs * Status indicator for each job * Sort and filter by status * Real-time status updates **Job Details:** * Detailed status information * Processing progress (if available) * Error messages (if failed) * Completion timestamp ### Processing Time Estimates | File Length | Estimated Processing Time | | ------------- | ------------------------- | | 1-5 minutes | 1-2 minutes | | 5-15 minutes | 2-4 minutes | | 15-30 minutes | 4-8 minutes | | 30-60 minutes | 8-15 minutes | | 1-2 hours | 15-30 minutes | Processing times are estimates. Actual time depends on audio quality, language complexity, and system load. Very long files (2+ hours) may take significantly longer. ## Validation and Error Handling ### File Upload Validation **File Format Errors:** * "Invalid file type" - File extension not supported * "File too large" - Exceeds 200MB limit * "Corrupted file" - File cannot be read **Solutions:** * Verify file format matches supported types * Compress large files or split into smaller files * Re-export corrupted files from source ### YouTube URL Validation **URL Errors:** * "Invalid YouTube URL" - URL format incorrect * "Video not accessible" - Private or restricted video * "Video too long" - Exceeds processing limits **Solutions:** * Verify URL format matches YouTube URL patterns * Ensure video is publicly accessible * Use shorter videos or split long videos ### Recording Validation **Recording Errors:** * "Microphone access denied" - Permission not granted * "Recording too short" - Less than 30 seconds * "Audio quality insufficient" - Poor recording quality **Solutions:** * Grant microphone permissions in browser settings * Record for at least 30 seconds * Improve recording environment and equipment ### Processing Errors **Common Processing Errors:** * "Audio extraction failed" - Cannot extract audio from video * "Transcription failed" - Processing error occurred * "Language detection failed" - Cannot determine language **Solutions:** * Check file is not corrupted * Verify language selection is correct * Try re-uploading with different settings * Contact support if errors persist ## Best Practices ### File Organization **Naming Conventions:** * Use descriptive, consistent names * Include dates for chronological organization * Use clear naming patterns **Examples:** ``` Good: "Team_Meeting_2024_01_15.mp3" Good: "Customer_Interview_Product_Feedback.wav" Bad: "recording1.mp3" Bad: "audio_final_v3.mp4" ``` ### Content Preparation **Audio Quality:** * Use clear, high-quality recordings * Minimize background noise * Ensure adequate volume levels * Avoid echo and distortion **File Management:** * Keep original files as backup * Organize files before uploading * Verify file integrity before upload * Archive completed transcriptions ### Workflow Optimization **Batch Processing:** * Upload one file at a time * Process files sequentially * Use consistent naming for organization * Track processing status **Quality Control:** * Review transcriptions after completion * Edit transcripts for accuracy * Organize speakers properly * Export in appropriate formats ## Next Steps After creating transcription jobs: 1. **[Managing Transcripts](./managing-transcripts)** - Organize and manage your transcription jobs 2. **[Speaker Management](./speaker-management)** - Work with speaker separation and identification 3. **[Export Options](./export-options)** - Export transcripts in various formats 4. **[Overview](./overview)** - Learn about Speech to Text features ## Related Documentation Organize and manage your transcription jobs Work with speaker separation and identification Export transcripts in multiple formats Learn about Speech to Text features # Export Options Source: https://docs.tryhamsa.com/media/speech-to-text/export-options Export transcripts in multiple formats for different use cases ## Overview Speech to Text supports exporting transcripts in multiple formats to suit different needs. You can export completed transcripts in various document, structured data, and subtitle formats. Export options are available for completed transcripts. Open the transcript details view to access export options. ## Supported Export Formats ### Document Formats **DOCX (Microsoft Word)** * Full-featured document format * Preserves formatting * Editable in Word and other editors * Includes speaker names and timestamps * Best for: Editing, sharing, documentation **PDF (Portable Document Format)** * Fixed-layout document * Preserves formatting exactly * Readable on any device * Includes speaker names and timestamps * Best for: Sharing, archiving, printing **TXT (Plain Text)** * Simple text format * No formatting * Universal compatibility * Includes speaker names * Best for: Simple text extraction, copying **HTML (Web Format)** * Web-ready format * Can be viewed in browsers * Preserves some formatting * Includes speaker names and timestamps * Best for: Web publishing, embedding ### Structured Formats **JSON (JavaScript Object Notation)** * Structured data format * Machine-readable * Includes all metadata * Includes speaker information * Best for: Integration, programming, data processing **SRT (SubRip Subtitle)** * Subtitle file format * Used for video subtitles * Includes timestamps * Standard subtitle format * Best for: Video subtitles, closed captions ## Export Process ### Accessing Export Options 1. **Open Transcript** * Navigate to Speech to Text list * Click on transcript to open details view * Or click "View" button 2. **Find Export Options** * Look for export/download button * Usually in header or actions menu * Multiple format options available 3. **Select Format** * Choose desired export format * Click format option * Download starts automatically ### Export Steps 1. **Select Format** * Click export button * Choose format from menu * Format-specific options may appear 2. **Processing** * System generates export file * Processing typically instant * Progress indicator shown 3. **Download** * File downloads to your device * Default download location used * Filename includes transcript title and format ## Format Details ### DOCX Format **Contents:** * Full transcript text * Speaker names for each segment * Timestamps (if included) * Formatted document structure **Features:** * Editable in Microsoft Word * Compatible with Google Docs * Preserves formatting * Professional appearance **Use Cases:** * Editing and refining transcripts * Creating documents from transcripts * Sharing with team members * Documentation purposes ### PDF Format **Contents:** * Full transcript text * Speaker names and timestamps * Formatted layout * Professional appearance **Features:** * Fixed layout * Readable on any device * Print-ready * Professional formatting **Use Cases:** * Sharing with stakeholders * Archiving transcripts * Printing transcripts * Official documentation ### TXT Format **Contents:** * Plain transcript text * Speaker names * Simple text format * No formatting **Features:** * Universal compatibility * Small file size * Easy to process * Simple structure **Use Cases:** * Text extraction * Simple text processing * Copying text content * Basic text needs ### HTML Format **Contents:** * Formatted transcript * Speaker names and timestamps * HTML structure * Styled layout **Features:** * Viewable in browsers * Preserves formatting * Can be embedded * Web-ready **Use Cases:** * Web publishing * Embedding in websites * HTML email content * Web-based sharing ### JSON Format **Contents:** * Complete transcript data * All metadata * Speaker information * Timestamps and segments * Structured data format **Features:** * Machine-readable * Complete data structure * Programmatic access * Integration-friendly **Use Cases:** * API integration * Data processing * Programming applications * Database import * Automation workflows **JSON Structure Example:** ```json theme={null} { "id": "transcript-id", "title": "Transcript Title", "segments": [ { "speaker": "Speaker Name", "text": "Segment text", "startTime": "00:00:00", "endTime": "00:00:05" } ], "speakers": [...], "metadata": {...} } ``` ### SRT Format **Contents:** * Subtitle entries * Sequential numbering * Timestamps (start and end) * Text content **Features:** * Standard subtitle format * Video player compatible * Timestamp precision * Sequential segments **Use Cases:** * Video subtitles * Closed captions * Video editing * Accessibility **SRT Format Example:** ``` 1 00:00:00,000 --> 00:00:05,000 Speaker Name: First segment text 2 00:00:05,000 --> 00:00:10,000 Speaker Name: Second segment text ``` ## Export Best Practices ### Format Selection **For Editing:** * Use DOCX for Word editing * Use TXT for simple text editing * Use HTML for web editing **For Sharing:** * Use PDF for professional sharing * Use HTML for web sharing * Use DOCX for collaborative editing **For Integration:** * Use JSON for programming * Use TXT for simple processing * Use SRT for video integration **For Archiving:** * Use PDF for long-term storage * Use JSON for data preservation * Use DOCX for editable archives ### File Naming **Default Naming:** * Includes transcript title * Includes format extension * Example: "Meeting\_2024\_01\_15.docx" **Custom Naming:** * Rename after download if needed * Use consistent naming patterns * Include dates and identifiers ### Quality Control **Before Export:** * Review transcript accuracy * Organize speakers properly * Edit segments as needed * Verify content completeness **After Export:** * Review exported file * Verify format correctness * Check speaker names included * Verify timestamps (if applicable) ## Integration Use Cases ### Video Subtitles **Workflow:** 1. Transcribe video audio 2. Edit and organize transcript 3. Export as SRT 4. Import into video editor 5. Sync with video timeline **Benefits:** * Accurate subtitles * Professional quality * Time-aligned content * Multiple language support ### Documentation **Workflow:** 1. Transcribe meeting or interview 2. Edit transcript for accuracy 3. Organize speakers 4. Export as DOCX or PDF 5. Distribute to team **Benefits:** * Professional documentation * Easy to share * Editable format * Searchable content ### Data Processing **Workflow:** 1. Transcribe multiple recordings 2. Export as JSON 3. Process with scripts 4. Analyze data 5. Generate reports **Benefits:** * Automated processing * Structured data * Programmatic access * Scalable workflows ### Web Publishing **Workflow:** 1. Transcribe content 2. Edit and format 3. Export as HTML 4. Embed in website 5. Publish online **Benefits:** * Web-ready format * Easy embedding * Maintains formatting * Accessible content ## Limitations and Considerations ### Format Limitations **DOCX:** * Requires Word or compatible editor * Larger file size than TXT * Formatting may vary by editor **PDF:** * Not easily editable * Fixed layout * Larger file size **TXT:** * No formatting * Limited structure * Basic content only **JSON:** * Requires JSON parser * Not human-readable easily * Technical format **SRT:** * Subtitle format only * Specific use case * Limited editing options ### File Size Considerations **Large Transcripts:** * DOCX and PDF can be large * JSON maintains structure * TXT is most compact * Consider file size for sharing ### Compatibility **Cross-Platform:** * PDF: Universal compatibility * TXT: Universal compatibility * DOCX: Requires compatible software * JSON: Requires JSON parser * HTML: Requires browser or editor * SRT: Requires video software ## Troubleshooting ### Export Not Working **Possible Causes:** * Transcript not completed * Network error * Browser download blocked * File size too large **Solutions:** * Verify transcript is completed * Check network connection * Check browser download settings * Try different format ### Format Issues **Problem:** * File doesn't open correctly * Formatting looks wrong * Missing content **Solutions:** * Try different format * Verify file downloaded completely * Check file extension * Use appropriate software ### Missing Data **Problem:** * Speaker names missing * Timestamps missing * Segments missing **Solutions:** * Verify transcript is complete * Check export format supports data * Review transcript before export * Try different format ## Next Steps * **[Managing Transcripts](./managing-transcripts)** - Organize and manage your transcripts * **[Speaker Management](./speaker-management)** - Organize speakers before export * **[Creating Transcriptions](./creating-transcriptions)** - Create transcripts to export * **[Overview](./overview)** - Learn about Speech to Text features ## Related Documentation Organize and manage your transcription jobs Organize speakers before export Create transcripts to export Learn about Speech to Text features # Managing Transcripts Source: https://docs.tryhamsa.com/media/speech-to-text/managing-transcripts Organize, search, filter, and manage your transcription jobs ## Overview The Speech to Text list view provides comprehensive management capabilities: * **Search** transcripts by title * **Filter** by status, media type * **Sort** by created date or total cost * **View** transcript details * **Edit** transcript titles * **Delete** transcripts with confirmation * **Export** transcripts in multiple formats All management actions are available from the Speech to Text list view. Click any transcript to open the details view for editing and export. ## List View Overview The transcription jobs list displays all your transcripts in a table format. ### Displayed Information | Column | Description | Sortable | | -------------- | --------------------------------------------- | -------- | | **Title** | Transcript job title/name | No | | **Status** | Processing state (Pending, Completed, Failed) | No | | **Created At** | When transcript was created | Yes | | **Media Type** | Source type (Upload, YouTube, Recording) | No | | **Total Cost** | Credits used for transcription | Yes | | **Actions** | View, edit, delete options | No | ### Visual Indicators **Status Colors:** * 🟡 **Pending**: Job is queued for processing * 🟢 **Completed**: Transcription finished successfully * 🔴 **Failed**: Processing encountered an error **Media Type Icons:** * 📁 **Upload**: File upload source * ▶️ **YouTube**: YouTube video source * 🎤 **Recording**: Live recording source ## Search Functionality ### Searching by Title The search bar allows real-time searching by transcript title: 1. **Enter Search Query** * Type in the search bar at the top * Search is case-insensitive * Searches transcript titles only * Results update as you type 2. **View Results** * Matching transcripts are shown * Non-matching transcripts are hidden * Search works with filters 3. **Clear Search** * Click the X button or clear the search field * All transcripts are shown again **Example Searches:** ``` "meeting" → Finds transcripts with "meeting" in title "2024" → Finds transcripts with "2024" in title "interview" → Finds all interview-related transcripts ``` Use descriptive titles when creating transcripts to make searching easier. Include keywords like date, topic, or participant names. ## Filtering Options The Speech to Text list supports multiple filter types that can be combined: ### Filter by Status Filter transcripts by their processing status: **Options:** * **Pending** - Queued for processing * **Completed** - Finished successfully * **Failed** - Processing error occurred **Use Case:** * Find transcripts that need attention (failed statuses) * View only completed, ready-to-use transcripts ### Filter by Media Type Filter transcripts by their source type: **Options:** * **All Types** (default) * **Upload** - File uploads * **YouTube** - YouTube videos * **Recording** - Live recordings **Use Case:** * Find all uploaded file transcripts * Locate YouTube video transcriptions * Review live recording transcripts ## Sorting Options Sort transcripts by different criteria: ### Sort by Created Date **Options:** * **Ascending** - Oldest transcripts first * **Descending** (default) - Most recent first **Use Case:** * Find recently created transcripts * Review oldest transcripts for cleanup * Track transcript creation timeline ### Sort by Total Cost **Options:** * **Ascending** - Least expensive first * **Descending** - Most expensive first **Use Case:** * Monitor credit usage * Identify high-cost transcripts * Budget tracking ## Transcript Actions Each transcript has an actions menu with the following options: ### View Transcript Open the transcript details view: 1. Click the **"View"** button or transcript title 2. Transcript details page opens 3. View full transcript with segments 4. Edit segments and speakers 5. Export transcript The view action opens the detailed transcript page where you can edit, manage speakers, and export. Note that edits can only be done on completed jobs. ### Edit Title Update the transcript's display title directly from the header: 1. Click the transcript title or the pen icon next to the title 2. Edit the title inline 3. Press Enter to save the changes **Title Guidelines:** * Use descriptive, clear names * Include dates for chronological organization * Include key topics or participants * Maximum length: 255 characters **Examples:** ``` Good: "Team Meeting - January 15, 2024" Good: "Customer Interview - Product Feedback" Bad: "transcript1", "audio", "recording" ``` ### Delete Transcript Remove a transcript from your list: **Process:** 1. Click the **Actions** menu (⋮) 2. Select **"Delete"** 3. Confirm deletion in dialog 4. Click **"Confirm"** or **"Delete"** Deletion is permanent and cannot be undone. Make sure you've exported any important transcripts before deleting. **Deletion Confirmation:** * Confirmation dialog appears * Requires explicit confirmation * Prevents accidental deletion ## Transcript Details View Click any transcript to open the detailed view: ### Overview Section **Basic Information:** * Transcript title (editable) * Creation date * Total cost (credits used) * Audio duration **Audio Player:** * Playback controls * Timeline scrubber * Playback speed control * Volume control * Download audio option ### Transcript Content **Segment View:** * All transcript segments displayed * Timestamp for each segment * Speaker identification * Text content for each segment * Click segment to play corresponding audio **Segment Actions:** * Edit segment text * Delete segment * Merge segments ### Speaker Management **Speaker List:** * All identified speakers * Speaker color coding * Segment count per speaker * Speaker name editing * Speaker merging options **Speaker Operations:** * Rename speakers * Add new speakers * Merge speakers * Delete speakers (with validation) ### Editing Capabilities **Text Editing:** * Inline text editing * Edit individual segments * Copy and paste text **Segment Operations:** * Create new segments * Delete segments * Merge segments ## Pagination ### Page Navigation The list view uses pagination for large numbers of transcripts: **Controls:** * **Previous Page**: Go to previous page * **Next Page**: Go to next page * **Page Numbers**: Jump to specific page **Features:** * Maintains filters and search across pages * Shows total number of transcripts * Displays current page information * Efficient loading of large datasets ### Reset Filters Clear all filters and search: 1. Click **"Reset"** or **"Clear Filters"** button 2. All filters return to defaults 3. Search is cleared 4. Sorting resets to default (newest first) 5. Returns to first page ## Troubleshooting ### Transcripts Not Appearing **Possible Causes:** * Filters are applied (check filter settings) * Search query is too specific * Transcript is on different page * Transcript failed to process **Solutions:** * Clear all filters * Clear search query * Check all pages * Verify transcript status ### Cannot Delete Transcript **Possible Causes:** * Transcript is currently processing * Permission issue **Solutions:** * Wait for processing to complete * Verify you have delete permissions * Contact support if issue persists ### Filter Not Working **Possible Causes:** * No transcripts match filter criteria * Filter not applied correctly * Browser cache issue **Solutions:** * Verify transcripts exist that match criteria * Clear and reapply filters * Refresh page * Clear browser cache ### Search Not Finding Transcripts **Possible Causes:** * Search term doesn't match title * Search is case-sensitive (shouldn't be) * Transcript title is different than expected **Solutions:** * Try different search terms * Check exact transcript title * Use partial words * Clear search and browse manually ## Export and Integration ### Quick Export From the list view: * Export options available in details view * Multiple format support * Bulk export (if available) ### Integration with Other Features **AI Docs:** * Use completed transcripts for AI Docs generation * Direct link from transcript to AI Docs * Preserves transcript context **Text to Speech:** * Use transcript text for TTS jobs * Copy text from transcripts * Generate speech from transcript content ## Next Steps * **[Creating Transcriptions](./creating-transcriptions)** - Learn how to create transcription jobs * **[Speaker Management](./speaker-management)** - Work with speaker separation and identification * **[Export Options](./export-options)** - Export transcripts in various formats * **[Overview](./overview)** - Learn about Speech to Text features ## Related Documentation Learn how to create transcription jobs Work with speaker separation and identification Export transcripts in multiple formats Learn about Speech to Text features # Overview Source: https://docs.tryhamsa.com/media/speech-to-text/overview Convert audio and video content into structured, editable text transcripts ## What is Speech to Text? Speech to Text (STT) converts audio and video content into structured, editable text transcripts. It is the foundational feature that enables content reuse across the platform, providing accurate transcription with speaker detection, time-based segmentation, and comprehensive management tools. **Speech to Text enables you to:** * Transcribe audio and video files into editable text * Automatically detect and separate speakers * Edit and refine transcriptions * Export transcripts in multiple formats * Manage multiple transcription jobs ## Core Capabilities ### Audio and Video Transcription Transform your media files into accurate text transcripts with support for: * **Multiple file formats**: MP3, MP4, WAV, AVI, MOV, WMV, WEBM * **File uploads**: Direct upload from your device (max 200MB) * **YouTube videos**: Transcribe directly from YouTube links * **Live recording**: Record audio directly in the browser * **Language selection**: Arabic by default with English support ### Speakers Detection and Separation Automatically identify and separate different speakers in your recordings: * **Automatic speaker separation**: Distinguishes between different speakers * **Speaker labeling**: Automatically assigns labels (Speaker 1, Speaker 2, etc.) * **Speaker management**: Rename, merge, and organize speakers * **Visual separation**: Clear visual indicators for different speakers ### Time-Based Segmentation Transcripts are organized into segments synchronized with audio playback: * **Automatic segmentation**: Content divided into manageable segments * **Timestamp synchronization**: Each segment linked to specific time points * **Audio playback**: Click segments to play corresponding audio * **Segment editing**: Edit individual segments independently ## Input Methods ### File Upload Upload audio or video files directly from your device: * **Supported formats**: MP3, MP4, WAV, AVI, MOV, WMV, WEBM * **Maximum size**: 200MB per file * **Multiple files**: Upload up to 5 files at once * **Drag and drop**: Easy file selection interface ### YouTube Link Transcription Transcribe videos directly from YouTube: * **URL input**: Paste YouTube video links * **Automatic extraction**: System extracts audio from video * **Video metadata**: Automatically retrieves video title * **Language selection**: Specify the primary language ### Live Audio Recording Record audio directly in your browser: * **In-browser recording**: No external software required * **Real-time monitoring**: See recording status and duration * **Pause and resume**: Full control over recording process * **Immediate processing**: Start transcription right after recording ## Transcript Management ### Viewing and Organization * **Transcript list**: View all your transcription jobs * **Status tracking**: Monitor job progress (In Progress, Completed, Failed) * **Search functionality**: Find transcripts by file name * **Filtering options**: Filter by status * **Pagination**: Navigate through large lists efficiently ### Editing Capabilities * **Inline editing**: Edit transcript text directly * **Segment-level editing**: Modify individual segments * **Copy and move**: Move text between segments * **Create segments**: Add new segments as needed * **Merge content**: Combine segments across speakers ### File Management * **Rename transcripts**: Update job titles * **Delete transcripts**: Remove jobs with confirmation dialog * **Job status**: Track processing status in real-time * **Job history**: Access previous transcription jobs ## Speaker Management ### Speaker Organization * **Automatic detection**: System identifies speakers automatically * **Speaker labels**: View all speakers in your transcript * **Rename speakers**: Assign meaningful names to speakers * **Add speakers**: Manually add new speakers if needed ### Speaker Operations * **Merge speakers**: Combine multiple speakers into one * **Validation**: System prevents invalid merge operations * **Deletion protection**: Cannot delete speakers with associated segments * **Speaker count**: Visual indicators for speaker distribution ## Segment Editing ### Segment Operations * **Edit segments**: Modify text content of individual segments * **Copy segments**: Duplicate segment content * **Move segments content**: Reorganize content between segments * **Create segments**: Add new segments manually * **Delete segments**: Remove unwanted segments ### Text Management * **Inline editing**: Direct text editing within segments * **Copy and paste**: Easy text manipulation * **Search within segments**: Find specific content * **Timestamp preservation**: Maintain audio synchronization ## Export Capabilities Export your transcripts in multiple formats: ### Document Formats * **DOCX**: Microsoft Word format for editing * **PDF**: Portable document format for sharing * **TXT**: Plain text format for simple use * **HTML**: Web-ready format with formatting ### Structured Formats * **JSON**: Structured data format for integration * **SRT**: Subtitle format for video synchronization ### Export Features * **One-click download**: Quick export in any format * **Format-specific formatting**: Optimized output per format * **Metadata preservation**: Includes timestamps and speaker information ## Processing States Transcription jobs move through different states: | Status | Description | Next Action | | ------------- | ----------------------------------- | ------------------------ | | **PENDING** | Transcription is being processed | Wait for completion | | **COMPLETED** | Transcription finished successfully | View and edit transcript | | **FAILED** | Processing encountered an error | Review error and retry | Failed jobs cannot be used until the error is resolved. Check the error message for details on what went wrong. ## Key Features ### Language Handling * **Bilingual support**: Handles arabic english bilingual content * **Language selection**: Specify language when creating job * **Accent recognition**: Handles various accents and dialects ### Real-Time Status Updates * **Live status tracking**: See job progress in real-time * **Status indicators**: Clear visual status indicators * **Completion notifications**: Get notified when jobs complete * **Error notifications**: Immediate feedback on failures ### Search and Filter * **Global search**: Search across all transcript titles * **Status filtering**: Filter by job status ## Use Cases ### Meeting Transcription Transcribe meetings and conferences: * Upload meeting recordings * Automatic speaker separation * Export transcription ### Content Creation Create high-quality written content from audio and video using Speech-to-Text and [AI Docs](/media/ai-docs/overview): * Accurately transcribe podcasts, interviews, and meetings * Transform audio recordings into well-structured blog posts and articles * Generate engaging social media posts from spoken content * Produce documentation from audio and video sources ### Accessibility Make content accessible: * Generate captions for videos * Create transcripts for audio content * Export in multiple formats ### Research and Documentation Document research and interviews: * Transcribe research interviews * Organize by speaker * Export for analysis * Maintain timestamps for reference ## Getting Started 1. **Create Your First Transcription** * Upload a file, paste a YouTube link, or record audio * Select the primary language * Enter a title for your transcript * Submit and wait for processing 2. **Review and Edit** * View your completed transcript * Edit segments as needed * Rename speakers * Organize content 3. **Export Your Transcript** * Choose your export format * Download your transcript * Share with your team ## What's Next? * **[Creating Transcriptions](./creating-transcriptions)** - Learn how to create transcription jobs * **[Managing Transcripts](./managing-transcripts)** - Organize and edit your transcripts * **[Speaker Management](./speaker-management)** - Work with speaker separation * **[Export Options](./export-options)** - Export in various formats # Speaker Management Source: https://docs.tryhamsa.com/media/speech-to-text/speaker-management Identify, organize, and manage speakers in your transcripts ## Overview Speaker Management allows you to identify, rename, organize, and merge speakers in your transcripts. The system automatically detects different speakers, and you can refine this identification to improve transcript accuracy and readability. Speaker management is available for completed transcripts. The system automatically identifies speakers, but you can refine speaker identification for better accuracy. ## Automatic Speaker Detection ### How It Works The system automatically identifies different speakers in your audio: * **Voice Pattern Analysis**: Analyzes voice characteristics * **Speaker Separation**: Distinguishes between different speakers * **Automatic Labeling**: Assigns labels (Speaker 1, Speaker 2, etc.) * **Color Coding**: Assigns colors for visual distinction ### Initial Speaker Labels When transcription completes: * Speakers are automatically identified * Labeled as "Speaker 1", "Speaker 2", etc. * Each speaker gets a unique color * Segments are assigned to speakers Automatic speaker detection works best with clear audio and distinct voices. Background noise or similar voices may require manual refinement. ## Viewing Speakers ### Speaker List The speaker list shows all identified speakers: **Displayed Information:** * Speaker name/label * Color indicator * Number of segments * Visual representation **Speaker List Features:** * Speaker count display * Quick access to speaker operations * Visual color coding ### Speaker Color Coding Each speaker is assigned a unique color: * Helps visually distinguish speakers * Consistent across transcript view * Automatically assigned ## Renaming Speakers ### Rename Process Give speakers meaningful names: 1. **Select Speaker** * Click on speaker in the speaker list 2. **Edit Name** * Click in the edit field * Enter new name * Press Enter to save 3. **Validation** * Name cannot be empty * Name must be unique * Case-insensitive uniqueness check **Naming Guidelines:** * Use descriptive names (e.g., "John Smith", "Interviewer") * Avoid generic names when possible * Use consistent naming patterns * Include role if helpful (e.g., "Manager - Sarah") **Examples:** ``` Good: "John Smith" Good: "Interviewer" Good: "Customer Service Rep" Bad: "Speaker 1", "Person", "Speaker" ``` ### Rename Validation **Requirements:** * Name must not be empty * Name must be unique (case-insensitive) * Cannot use existing speaker names * Maximum length: 255 characters **Error Handling:** * Error message if name is duplicate * Error message if name is empty * Prevents invalid renames * Shows clear error messages ## Adding Speakers ### When to Add Speakers Add speakers manually when: * System didn't detect a speaker * You need to add a known participant * Speaker identification missed someone * You want to organize segments differently ### Add Speaker Process 1. **Open Add Speaker Form** * Click "Add Speaker" button * Form appears in speaker list 2. **Enter Speaker Name** * Type speaker name * Follow naming guidelines * Ensure name is unique 3. **Save Speaker** * Click "Add" or press Enter * Speaker is created * Available for segment assignment **Speaker Addition:** * New speaker gets unique color * Can be assigned to segments * Appears in speaker list * Follows same naming rules as renaming ## Merging Speakers ### When to Merge Speakers Merge speakers when: * Same person identified as multiple speakers * System split one speaker into multiple * You want to consolidate speakers * Correcting identification errors ### Merge Process 1. **Select Source Speaker** * Click merge icon on source speaker * Source is the speaker to merge FROM 2. **Select Target Speaker** * Click target speaker * Target is the speaker to merge TO 3. **Confirm Merge** * Review segments to be merged * Confirm merge operation * Merging cannot be undone **Merge Behavior:** * All segments from source move to target * Target speaker retains its name * Segment assignments update automatically Merging speakers cannot be undone. Make sure you're merging to the correct target speaker before confirming. ### Merge Validation **Requirements:** * Source and target must be different * Both speakers must exist * Cannot merge if source has no segments * Prevents invalid merge operations **Error Handling:** * Error if source and target are same * Error if source has no segments * Clear error messages * Prevents accidental merges ## Deleting Speakers ### When to Delete Speakers Delete speakers when: * Speaker was incorrectly identified * Speaker has no segments * Cleaning up transcript organization * Removing unused speakers Speakers can only be deleted if there are no segments associated with them. If a speaker has segments, you must first reassign those segments to another speaker or merge the speaker into another speaker. ### Delete Process 1. **Select Speaker** * Click delete icon on speaker * Or select from speaker menu 2. **Confirm Deletion** * Review speaker information * Confirm deletion * Cannot be undone **Delete Behavior:** * Speaker is removed from list * Segments must be reassigned first * Cannot delete speaker with segments * Requires manual segment reassignment You cannot delete a speaker that has assigned segments. You must first reassign or delete those segments, or merge the speaker into another speaker. ### Delete Validation **Requirements:** * Speaker must have no segments * Or segments must be reassigned first * Cannot delete last speaker * Prevents data loss **Error Handling:** * Error if speaker has segments * Suggests merging instead * Clear error messages * Protects transcript integrity ## Segment Assignment ### Assigning Segments to Speakers After adding speakers, assign segments: 1. **Select Segment** * Click on segment in transcript * Segment highlights 2. **Change Speaker** * Click speaker dropdown * Select new speaker * Segment reassigns **Assignment Behavior:** * Segment moves to new speaker * Updates transcript organization * Maintains timestamp and content * Updates speaker segment counts ## Best Practices ### Speaker Identification **Before Renaming:** * Review automatic detection * Identify which speakers are which * Note any missed or incorrect identifications * Plan speaker organization **Naming Strategy:** * Use real names when known * Use roles when names unknown * Be consistent across transcripts * Use clear, descriptive names ### Quality Control **Review Process:** 1. Review automatic detection 2. Identify any issues 3. Rename speakers with meaningful names 4. Merge duplicate speakers 5. Assign segments correctly 6. Final review before export **Common Issues:** * Same person as multiple speakers → Merge * Wrong speaker on segments → Reassign * Missing speaker → Add manually * Unclear identification → Review audio ## Troubleshooting ### Speaker Not Detected **Possible Causes:** * Audio quality issues * Similar voices * Background noise * Speaker spoke too little **Solutions:** * Add speaker manually * Review audio quality * Merge if split across multiple speakers * Check if speaker segments exist ### Duplicate Speakers **Issue:** * Same person identified as multiple speakers **Solution:** * Merge duplicate speakers * Review all speakers first * Identify which to merge * Merge to most representative speaker ### Cannot Delete Speaker **Issue:** * Delete button disabled or shows error **Cause:** * Speaker has segments associated with it **Solution:** * Merge speaker into another speaker * Or reassign segments first * Then delete speaker ### Merge Not Working **Issue:** * Cannot merge speakers **Causes:** * Source and target are same * Source has no segments **Solutions:** * Verify source and target are different * Check source has segments * Retry operation ## Integration with Editing ### Editing and Speakers **Segment Editing:** * Editing segment text doesn't change speaker * Speaker assignment preserved * Can edit and change speaker independently **Speaker Changes:** * Changing speaker doesn't affect text * Text content preserved * Only assignment changes ## Next Steps * **[Managing Transcripts](./managing-transcripts)** - Organize and manage your transcripts * **[Creating Transcriptions](./creating-transcriptions)** - Learn how to create transcription jobs * **[Export Options](./export-options)** - Export transcripts with speaker information * **[Overview](./overview)** - Learn about Speech to Text features ## Related Documentation Organize and manage your transcription jobs Learn how to create transcription jobs Export transcripts with speaker information Learn about Speech to Text features # Creating TTS Jobs Source: https://docs.tryhamsa.com/media/text-to-speech/creating-jobs Step-by-step guide to creating text-to-speech jobs ## Overview Creating a Text to Speech job involves entering text, selecting a voice, adjusting controls, and generating audio. The system processes your text and generates high-quality speech audio that you can preview, download, or use in other applications. TTS jobs are processed in real-time or near real-time. Most jobs complete within seconds to minutes depending on text length. You can preview audio while it's being generated. ## Step-by-Step Process ### Step 1: Navigate to Text to Speech 1. Click on **Text to Speech** in the navigation menu 2. The TTS interface opens with the text editor and voice controls Navigate to Text to Speech in the navigation menu Navigate to Text to Speech in the navigation menu ### Step 2: Enter Text Content Enter or paste the text you want to convert to speech: **Text Input Options:** * **Type directly**: Type text in the text editor * **Paste text**: Copy and paste text from another source **Text Input Best Practices:** * Use clear, well-formatted text * Add punctuation for natural pauses * Break long paragraphs into shorter ones * Check spelling and grammar Very long texts may take longer to process and consume more credits. Consider breaking very long content into multiple jobs if needed. ### Step 3: Select a Voice Choose the voice you want to use for speech generation. Click on the voice selection area to open the **voice selection modal**. **Modal tabs:** * **Explore**: Handpicked collections by use case (e.g. Arabic Narration, Social Media, Studio Conversational, Character Voices) and a "Weekly spotlight - New Voices" list. Use this to discover voices by context. * **My Voices**: Your favorite voices in one place for quick access. * **All Voices**: Full voice library with infinite scroll. **Finding voices:** * **Search**: Type a voice name in the search field for instant results. * **Filter**: Narrow by language, gender, style, dialect, or use case. Use "Clear filters" to reset. * **Explore collections**: On the Explore tab, click a collection card to see voices for that use case. **Selecting a voice:** 1. Open the voice selection area to open the modal. 2. Switch between **Explore**, **My Voices**, or **All Voices** as needed. 3. Preview a voice by clicking the **play** icon on a voice row. 4. Click the voice (or **Select** in the modal) to apply it to your job. The modal closes and the chosen voice is shown in the TTS interface. **Voice types in the library:** * **System voices**: Pre-trained voices from the library (Arabic and English, multiple styles and dialects). * **Custom voices**: Your cloned or custom voices, same controls as system voices. * **Favorites**: Voices you've marked as favorites appear under **My Voices**. You can preview any voice before selecting it. Click the play icon next to a voice to hear a sample. ### Step 4: Adjust Voice Controls (Optional) Fine-tune the voice characteristics: **Expressiveness Control:** * **Range**: 0 to 2 (default: 1) * **Adjustment**: Drag slider or enter value * **Effect**: Controls emotional range and variation * **Use cases**: More neutral for consistency, more expressive for dynamics Start with default settings and adjust based on your needs. You can always regenerate with different settings. ### Step 5: Configure Additional Settings (Optional) **Dictionaries (Optional):** * Open **Manage** (or "Click To Manage Dictionaries") in the Dictionaries section to open the Dictionaries modal * **Add** a new dictionary with "+ New Dictionary"; **delete** a dictionary using the trash icon next to it * **Add and edit words** inside a dictionary: click the pencil (edit) icon on a dictionary to open the editor, then add word–pronunciation pairs and save * **Select** which dictionaries apply to this TTS job by checking the box next to each dictionary in the list; selected dictionaries apply custom pronunciation rules * Useful for technical terms, proper nouns, or brand names ### Step 6: Generate Audio Create the TTS job: 1. **Review Settings** * Check text content * Verify voice selection * Review control settings * Ensure everything is correct 2. **Click Generate** * Click **"Generate Speech"** button * Job is created and processing starts 3. **Monitor Progress** * Live audio viewer shows progress while job is being generated * Processing typically completes quickly * Audio preview available when ready 4. **Job Completion** * Audio is available for playback * Download and share options available ## Text Input Details ### Text Editor Features **Editing Capabilities:** * **Inline editing**: Edit text directly in the editor * **Copy and paste**: Full clipboard support * **Undo/redo**: Standard text editing functions * **Character count**: Real-time character counting ## Voice Selection Details ### Browsing Voices **Voice Library:** * Scroll through available voices * See voice names and metadata * Preview voices with play button * Filter and search options **Voice Information:** * **Name**: Voice identifier * **Language**: Supported language * **Dialect**: Regional variant * **Gender**: Male or female * **Style**: Narrator, Conversational, etc. ### Filtering Voices **Filter Options:** * **Language**: Filter by language (Arabic, English, etc.) * **Gender**: Filter by gender (Male, Female) * **Style**: Filter by style (Narrator, Conversational) * **Dialect**: Filter by regional dialect **Search Voices:** * Search by voice name only * Case-insensitive search * Real-time results * Clear search to reset ### Voice Preview **Preview Features:** * Click play icon to hear sample * Sample audio plays automatically * Compare different voices * Helps choose right voice **Preview Best Practices:** * Preview multiple voices * Compare similar voices * Listen to sample quality * Choose voice that matches content ### Favorite Voices **Marking Favorites:** * Click star icon on voice * Voice added to favorites * Quick access in favorites section * Personal voice library **Using Favorites:** * Access favorites quickly * Filter to show only favorites * Organize frequently used voices * Save time on voice selection ## Voice Controls Details **Expressiveness Guidelines:** * **0 - 0.5**: Neutral, consistent delivery * **0.6 - 1.0**: Balanced, natural variation * **1.1 - 1.5**: Expressive, dynamic delivery * **1.6 - 2.0**: Very expressive, emotionally varied **Use Cases:** * Neutral for formal content * Balanced for general content * Expressive for engaging content * Very expressive for dramatic content ## Job Creation and Processing ### Job Creation **Job Information:** * Job ID assigned automatically * Title (if supported) * Creation timestamp **Job Storage:** * Job saved to history * Accessible from jobs list * Can be viewed, edited, or deleted * Links to generated audio **Processing Time:** * Typically seconds to minutes * Depends on text length * Real-time or near real-time for short text * Longer for very long text ### Audio Generation **Generation Process:** 1. Text is processed 2. Voice model applied 3. Controls applied 4. Audio generated 5. Available for playback **Audio Quality:** * High-quality output * Natural speech patterns * Clear pronunciation * Professional quality ## Credit Usage ### Cost Calculation **Credit Usage:** * Based on audio duration * Credits per minute displayed * Total cost estimated before generation * Actual cost shown after completion **Cost Factors:** * Audio length (minutes) * Credit rate per minute * Voice type (some voices may vary) * No additional charges for controls ## Best Practices ### Text Preparation **Content Quality:** * Use clear, well-written text * Check spelling and grammar * Add appropriate punctuation * Break long text into paragraphs **Text Optimization:** * Use optimize button for Arabic * Add punctuation for pauses * Consider text length * Review before generating ### Voice Selection **Choosing the Right Voice:** * Match voice to content type * Consider target audience * Preview multiple voices * Use favorites for consistency **Voice Consistency:** * Use same voice for series * Mark frequently used voices as favorites * Maintain voice across related content * Create voice guidelines ### Control Settings **Starting Point:** * Begin with default settings * Adjust based on content * Test different settings * Save preferred settings **Setting Guidelines:** * Speed: Match content pace * Expressiveness: Match content tone * Adjust gradually * Preview before final generation ### Job Management **Organization:** * Use descriptive titles (if supported) * Organize jobs by project * Review job history regularly * Delete unused jobs **Quality Control:** * Preview audio before using * Review generated audio * Regenerate if needed * Export high-quality versions ## Troubleshooting ### Text Input Issues **Problem**: Text not accepted **Solutions**: * Check text length limits * Verify text format * Remove special characters if needed * Try simpler text ### Voice Selection Issues **Problem**: Voice not available **Solutions**: * Check voice filters * Clear search/filters * Verify voice availability * Try different voice ### Generation Issues **Problem**: Job fails to generate **Solutions**: * Check text content * Verify voice selection * Check credit balance * Try again with simpler text ### Audio Quality Issues **Problem**: Audio quality poor **Solutions**: * Check text quality * Try different voice * Adjust controls * Review text formatting ## Next Steps After creating a TTS job: 1. [**Voice Selection**](./voice-selection) - Learn about voice options and selection 2. [**Voice Controls**](./voice-controls) - Understand control settings 3. [**Managing Jobs**](./managing-jobs) - Organize and manage your TTS jobs 4. [**Overview**](./overview) - Learn about Text to Speech features ## Related Documentation Learn about voice options and selection Understand control settings and adjustments Organize and manage your TTS jobs Learn about Text to Speech features # Managing Jobs Source: https://docs.tryhamsa.com/media/text-to-speech/managing-jobs Organize, view, and manage your text-to-speech jobs ## Overview The Text to Speech jobs list allows you to view, organize, and manage all your TTS generation jobs. You can access job history, view details, download audio, and manage your generated content. All your TTS jobs are saved to your job history. You can access them anytime to review, download, or regenerate with different settings. ## Jobs List View ### Viewing Jobs **Jobs List Display:** * All your TTS jobs in a list * Job information visible * Status indicators * Quick actions available **Displayed Information:** * Job title/preview * Voice used * Creation date * Status (Completed, Failed, etc.) * Audio duration (if available) ### Job Status **Status Types:** * **Completed**: Audio generated successfully * **Failed**: Generation encountered error * **Processing**: Currently generating (if applicable) ## Job Operations ### View Job **View Job Details:** 1. Click on job in list 2. Job details open 3. View full information 4. Access audio playback **Job Details Include:** * Full text content * Voice information * Control settings used * Generation timestamp * Audio file ### Play Audio **Audio Playback:** * Click play button * Audio plays in browser * Playback controls available * Download option available **Playback Features:** * Play/pause controls * Timeline scrubber * Volume control * Playback speed (if available) ### Download Audio **Download Options:** * Click download button * Audio downloads to device * Default download location * Filename includes job info **Audio Formats:** * MP3 format (common) * WAV format (if available) * High-quality audio * Professional quality ### Delete Job **Delete Process:** 1. Click delete/remove button 2. Confirm deletion 3. Job removed from list 4. Cannot be undone Deleting a job is permanent. Make sure you've downloaded any audio you want to keep before deleting. ### Remix Job **Create New from Existing:** * Use existing job as starting point * Modify text or settings * Generate new version * Useful for variations **Remix Options:** * Keep text, change voice * Keep voice, change text * Adjust controls * Create variations ## Job Organization ### Filter Jobs **Filter Options (if available):** * Filter by status * Filter by voice * Filter by date * Combine filters **Organization:** * Group by voice * Group by date * Group by status * Custom organization ## Best Practices ### Job Management **Organization:** * Use descriptive text previews * Review job history regularly * Delete unused jobs * Keep important jobs **Backup:** * Download important audio * Save audio files locally * Archive completed jobs * Maintain backups ### Quality Control **Review Process:** * Listen to generated audio * Verify quality meets needs * Regenerate if needed * Document preferred settings **Consistency:** * Use same voice for series * Maintain consistent settings * Document voice preferences * Create style guidelines ## Troubleshooting ### Job Not Showing **Issue:** Job doesn't appear in list **Solutions:** * Check filters * Refresh page * Verify job was created * Check different view ### Audio Not Playing **Issue:** Audio playback fails **Solutions:** * Check audio file exists * Try download instead * Check browser audio * Verify file format ### Download Issues **Issue:** Cannot download audio **Solutions:** * Check download permissions * Try different browser * Check file size * Verify job completed ## Next Steps * **[Creating Jobs](./creating-jobs)** - Learn how to create TTS jobs * **[Voice Selection](./voice-selection)** - Choose voices for jobs * **[Voice Controls](./voice-controls)** - Adjust voice settings * **[Overview](./overview)** - Learn about Text to Speech features ## Related Documentation Learn how to create TTS jobs Choose the right voice Adjust voice settings Learn about Text to Speech features # Overview Source: https://docs.tryhamsa.com/media/text-to-speech/overview Convert written content into human-like audio using configurable voice models ## What is Text to Speech? Text to Speech (TTS) converts written content into human-like audio using configurable voice models. It enables you to generate natural-sounding speech with advanced controls for voice selection, speed, expressiveness, and output quality. **Text to Speech enables you to:** * Convert text to natural-sounding speech * Choose from a wide selection of voice options * Adjust voice characteristics (speed, expressiveness) * Generate long-form audio content * Download audio in multiple formats ## Core Capabilities ### Long-Form Text Input Process large amounts of text efficiently: * **Text length limit**: Character limit applies per request * **Inline text editing**: Edit text directly in the interface * **Character count tracking**: Monitor text length * **Multi-language support**: Support for Arabic and English with multiple dialects ### Human-Like Voice Synthesis Generate natural, expressive speech: * **High-quality voices**: Professional-grade voice models * **Emotional expression**: Control expressiveness and tone * **Natural pauses**: Automatic and manual pause insertion * **Dialect support**: Multiple Arabic dialects ### Job-Based Generation Organized generation workflow: * **Job creation**: Create jobs for each generation task * **Job history**: Access all previous generations * **Job management**: Edit, delete, and remix jobs ## Text Input Capabilities ### Text Editing * **Inline editing**: Direct text editing in the interface * **Paste support**: Easy text input from clipboard * **Character counting**: Real-time character count display * **Multi-line support**: Handle paragraphs and line breaks ### Advanced Text Features * **Emotion markers**: Add emoji-based emotion indicators (😊, 😢, etc.) * **Silence breaks**: Insert pauses for natural pacing * Short breaks: Brief pauses between phrases * Long breaks: Extended pauses for emphasis * **Fillers**: Add natural filler words (Uh, Umm) for realism ### Text Optimization Tools * **Silence controls**: Add strategic pauses * **Emotion adjustment**: Enhance emotional delivery ## Voice Selection Capabilities ### System Voices Choose from a library of pre-trained voices: * **Extensive library**: Wide selection of voices * **Multiple languages**: Support for Arabic and English * **Gender options**: Male and female voices * **Dialect variety**: Multiple dialects per language * **Style options**: Narrator, Conversational, and more ### Custom (Cloned) Voices Use your own custom voices: * **Cloned voices**: Voices created from audio samples * **Voice library**: Access to your custom voice collection * **Voice preview**: Test voices before generation * **Favorite voices**: Mark frequently used voices * **Recent voices**: Quick access to recently used voices ### Voice Metadata View detailed voice information: * **Voice name**: Identifiable voice names * **Gender**: Male or female * **Dialect**: Language and regional dialect * **Style**: Voice style (Narrator, Conversational) * **Language code**: Technical language identifiers ### Voice Organization * **Favorites**: Mark voices for quick access * **Recent usage**: View recently used voices * **Voice filtering**: Filter by language, gender, style * **Voice search**: Search voices by name * **Voice preview**: Play sample audio before selection ## Voice Control Capabilities ### Speed Adjustment Control how fast the voice reads: * **Speed range**: 0x to 2x (default: 1x) * **Fine control**: Adjust in 0.1 increments * **Slow option**: Slower for clear, natural delivery * **Fast option**: Faster for quicker playback * **Real-time preview**: Hear changes immediately ### Expressiveness Adjustment Control the emotional range and variation: * **Expressiveness range**: 0 to 2 (default: 1) * **More neutral**: Natural, consistent delivery * **More expressive**: Dynamic, emotionally varied delivery * **Fine-tuning**: Precise control over emotional range * **Voice-specific optimization**: Adapts to selected voice ## Generation Management Capabilities ### Job List View * **Job history**: View all generation jobs * **Job metadata**: Voice, language, creation date * **Quick actions**: View, download, delete from list ### Job Operations * **View job**: Open job details and audio * **Edit job**: Modify text and regenerate (resets status) * **Delete job**: Remove completed or failed jobs * **Remix job**: Create new job based on existing one * **Download audio**: Get audio file directly ## Output Capabilities ### Audio Playback * **In-browser playback**: Listen directly in the interface * **Playback controls**: Play, pause, seek * **Streaming playback**: Start playback while generating * **Audio quality**: High-quality audio output * **Multiple formats**: Support for various audio formats ### Audio Download Export audio files: * **MP3 format**: Compressed audio format * **One-click download**: Direct download from interface ## Dictionaries and Customization ### Voice Dictionaries Customize pronunciation: * **Dictionary selection**: Choose dictionaries for voices * **Custom pronunciations**: Override default pronunciations * **Multiple dictionaries**: Use multiple dictionaries per job * **Dictionary management**: Create and manage dictionaries ## Use Cases ### Content Creation Generate audio for various content: * **Podcast intros**: Create podcast introductions * **Audiobooks**: Convert text to audiobook format * **Video narration**: Generate voiceovers for videos * **Educational content**: Create learning materials ### Marketing and Advertising Create marketing audio: * **Advertisement voiceovers**: Commercial audio * **Social media content**: Audio for platforms * **Brand voice**: Consistent voice across content * **Multilingual campaigns**: Same content in multiple languages ### Customer Service Enhance customer interactions: * **IVR systems**: Automated phone systems * **Voice prompts**: System announcements * **Notification audio**: Alert sounds and messages * **Training materials**: Audio training content ## Key Features ### Real-Time Generation * **Streaming generation**: Start playback while generating * **Progressive loading**: Audio available as it generates * **Status updates**: Real-time progress indicators * **Error handling**: Clear error messages and recovery ### Voice Quality * **High fidelity**: Professional-grade audio quality * **Natural intonation**: Human-like speech patterns * **Emotion support**: Expressive delivery options * **Consistency**: Stable voice characteristics ## Getting Started 1. **Enter Your Text** * Type or paste text into the editor * Add emotion markers and pauses if needed * Optimize text for better results 2. **Select a Voice** * Browse available voices * Preview voice samples * Select your preferred voice 3. **Adjust Controls** * Set speed and expressiveness * Fine-tune voice characteristics * Preview changes in real-time 4. **Generate Audio** * Click generate and wait for processing * Listen to your audio * Download or share as needed ## What's Next? * **[Creating TTS Jobs](./creating-jobs)** - Learn how to create text-to-speech jobs * **[Voice Selection](./voice-selection)** - Choose and customize voices * **[Voice Controls](./voice-controls)** - Adjust speed and expressiveness * **[Managing Jobs](./managing-jobs)** - Organize and manage generation jobs # Voice Controls Source: https://docs.tryhamsa.com/media/text-to-speech/voice-controls Adjust speed, expressiveness, and other voice parameters ## Overview Voice controls allow you to fine-tune how the selected voice delivers your text. You can adjust speed, expressiveness, and other parameters to match your content style and audience preferences. Voice controls are optional. You can use default settings for good results, or fine-tune controls to achieve the perfect delivery for your content. ## Speed Control ### Speed Adjustment Control how fast the voice reads your text: **Speed Range:** * **Minimum**: 0x (very slow) * **Maximum**: 2x (very fast) * **Default**: 1x (normal speed) * **Step Size**: 0.1x increments **Adjustment Methods:** * Drag slider left/right * Click on slider track * Enter value directly (if supported) * Use increment buttons (if available) ### Speed Guidelines **Very Slow (0.5x - 0.8x):** * Clear, deliberate delivery * Easy to follow * Good for complex information * May sound unnatural if too slow **Normal Speed (0.9x - 1.1x):** * Natural conversational pace * Balanced delivery * Good for most content * Default recommended setting **Fast (1.2x - 1.5x):** * Quick, energetic delivery * Time-efficient playback * Good for summaries * Maintains clarity **Very Fast (1.6x - 2.0x):** * Very quick playback * Maximum time efficiency * May reduce clarity * Use with caution ### Speed Use Cases **Slow Speed:** * Important instructions * Complex information * Educational content * Audience learning new language **Normal Speed:** * General content * Most use cases * Standard delivery * Recommended default **Fast Speed:** * Quick summaries * Time-constrained content * Review material * Energetic delivery ## Expressiveness Control ### Expressiveness Adjustment Control the emotional range and variation in the voice: **Expressiveness Range:** * **Minimum**: 0 (more neutral) * **Maximum**: 2 (more expressive) * **Default**: 1 (balanced) * **Step Size**: 0.1 increments **Adjustment Methods:** * Drag slider left/right * Click on slider track * Enter value directly (if supported) * Fine-tune gradually ### Expressiveness Guidelines **More Neutral (0 - 0.5):** * Consistent, steady delivery * Minimal emotional variation * Professional, formal tone * Good for factual content **Balanced (0.6 - 1.0):** * Natural variation * Moderate expressiveness * Good for general content * Default recommended setting **More Expressive (1.1 - 1.5):** * Dynamic, varied delivery * Emotional engagement * Good for engaging content * More personality **Very Expressive (1.6 - 2.0):** * Highly dynamic delivery * Strong emotional variation * Dramatic presentation * Use for special content ### Expressiveness Use Cases **Neutral:** * News reporting * Technical documentation * Formal presentations * Objective content **Balanced:** * General content * Most use cases * Standard delivery * Recommended default **Expressive:** * Marketing content * Storytelling * Engaging presentations * Emotional content ## Control Interaction ### Speed and Expressiveness Together **Combined Effects:** * Speed affects pacing * Expressiveness affects delivery style * Work together for overall effect * Adjust both for best results **Recommended Combinations:** * **Formal**: Normal speed + Neutral expressiveness * **Engaging**: Normal speed + Expressive * **Quick Summary**: Fast speed + Neutral * **Dramatic**: Normal speed + Very expressive ## Control Best Practices ### Starting Point **Default Settings:** * Start with defaults (1x speed, 1 expressiveness) * Good for most content * Professional quality * Can adjust from there **Testing:** * Test with sample text * Compare different settings * Listen to results * Adjust based on feedback ### Adjustment Strategy **Gradual Changes:** * Adjust in small increments * Test after each change * Compare before/after * Find optimal settings **Content-Based:** * Match controls to content type * Consider audience preferences * Test with target audience * Document preferred settings ### Settings Documentation **Record Settings:** * Note preferred settings * Document for consistency * Share with team * Create style guide **Settings Guidelines:** * Establish default settings * Create settings templates * Train team on settings * Maintain consistency ## Advanced Controls ### Dictionaries (If Available) **Pronunciation Customization:** * Select voice dictionaries * Custom pronunciation rules * Technical terms * Proper nouns ### Text Optimization **Arabic Text Optimization:** * Optimize button for Arabic * Improves pronunciation * Adds natural pauses * Enhances quality ## Troubleshooting ### Controls Not Responding **Issue:** Sliders not working **Solutions:** * Refresh page * Check browser compatibility * Try different browser * Clear cache ### Settings Not Saving **Issue:** Controls reset **Solutions:** * Settings save with job * Check job creation process * Verify settings before generating * Settings apply to generation ### Quality Issues **Issue:** Audio quality poor with settings **Solutions:** * Return to defaults * Adjust gradually * Test different combinations * Review text quality ## Next Steps * **[Creating Jobs](./creating-jobs)** - Learn how to create TTS jobs * **[Voice Selection](./voice-selection)** - Choose the right voice * **[Managing Jobs](./managing-jobs)** - Organize your TTS jobs * **[Overview](./overview)** - Learn about Text to Speech features ## Related Documentation Learn how to create TTS jobs Choose the right voice for your content Organize and manage your TTS jobs Learn about Text to Speech features # Voice Selection Source: https://docs.tryhamsa.com/media/text-to-speech/voice-selection Choose and customize voices for text-to-speech generation ## Overview Voice selection is a critical part of creating high-quality text-to-speech audio. The platform offers hundreds of voices across Arabic and English, with various styles and dialects, allowing you to choose the perfect voice for your content. You can preview any voice before selecting it. Take time to listen to different voices to find the best match for your content and audience. ## Voice Types ### System Voices Pre-trained voices from the voice library: * **Wide selection of voices available** * **Languages**: Arabic, English * **Various styles**: Narrator, Conversational, etc. * **Different dialects**: Regional variations * **Gender options**: Male and female voices ### Custom Voices Voices created through voice cloning: * **Your custom voices**: Voices you've created * **Cloned voices**: Voices cloned from audio samples * **Personal library**: Your collection of custom voices * **Same controls**: Same settings as system voices ### Favorite Voices Voices you've marked as favorites: * **Quick access**: Easy to find frequently used voices * **Personal library**: Your preferred voices * **Consistent selection**: Use same voices across jobs * **Organization**: Organize your voice preferences ## Voice Selection Interface ### Voice Selection Modal When you click the voice selection area (e.g. in Text to Speech), a **voice selection modal** opens with three tabs: **Explore tab:** * **Handpicked collections**: Use-case collections such as Arabic Narration, Social Media, Studio-Quality Conversational, and Character Voices for Games. Click a collection to see voices for that use case. * **Weekly spotlight**: A "New Voices" featured list for recently added or curated voices. * Use Explore to discover voices by context before searching or filtering. **My Voices tab:** * Shows only voices you've marked as favorites. * Quick access to voices you use often. * Empty until you add favorites from Explore or All Voices. **All Voices tab:** * Full voice library with infinite scroll. * Use together with search and filters to narrow results. **Voice list (in modal):** * Each voice appears as a row with name and metadata. * **Play** icon to preview the voice sample. * **Favorite** (star) icon to add or remove from My Voices. * **Select** (or click the row) to choose the voice and close the modal (in TTS, the selected voice is applied to your job). **Voice information shown:** * Voice name * Language * Dialect/Region * Gender * Style (Narrator, Conversational, etc.) * Type (System or Custom) ### Voice Preview **Preview Features:** * Click play icon to hear sample * Sample audio plays automatically * Compare multiple voices * Preview before selecting **Preview Best Practices:** * Listen to full sample * Compare similar voices * Consider content context * Test with your text (if available) ## Voice Filtering ### Filter Options **By Language:** * Arabic * English **By Gender:** * Male voices * Female voices * Both (show all) **By Style:** * Narrator * Conversational * Other styles * All styles **By Dialect:** * Regional dialects * Language variants * Specific regions * All dialects **By Type:** * System voices * Custom voices * Favorites only * All voices ### Search Functionality **Search by Name:** * Type voice name * Case-insensitive search * Real-time results * Highlights matches **Search Tips:** * Use partial names * Search by language * Search by style * Clear search to reset ## Voice Selection Process ### Step 1: Open the Voice Selection Modal 1. Navigate to Text to Speech (or wherever voice selection is offered). 2. Click the **voice selection area** (current voice name or "Select voice"). 3. The voice selection modal opens with the **Explore** tab by default. ### Step 2: Find Voices (Tabs, Search, and Filters) **Use the tabs:** * **Explore**: Browse collections and the Weekly spotlight list. * **My Voices**: See only your favorite voices. * **All Voices**: Browse the full library with infinite scroll. **Search:** * Type a voice name in the search field for real-time results. * Works on any tab; results update as you type. **Filter:** * Use the filter bar to narrow by language, gender, style, dialect, or use case. * On Explore, applying filters shows a filtered voice list; use "Back to Explore" to return to collections. * Use "Clear filters" to reset. ### Step 3: Preview Voices 1. Click the **play** icon on a voice row. 2. Listen to the sample audio. 3. Compare multiple voices by playing each in turn. 4. Optionally mark voices as favorites (star) for **My Voices**. ### Step 4: Select a Voice 1. Click the desired voice row (or **Select** when in select mode). 2. The voice is selected and the modal closes. 3. The chosen voice is applied to your current job or context. 4. You can reopen the modal anytime to change the voice. ## Voice Metadata ### Understanding Voice Information **Voice Name:** * Identifier for the voice * Usually descriptive * May include language/dialect * Unique identifier **Language:** * Primary language supported (Arabic or English) * Language code displayed * Affects pronunciation **Dialect:** * Regional variation * Specific to language * Affects accent and pronunciation * Examples: Saudi Arabic, Egyptian Arabic **Gender:** * Male or Female * Voice gender identity * Affects voice characteristics * Choose based on preference **Style:** * Narrator: Formal, reading style * Conversational: Casual, talking style * Other specialized styles * Affects delivery style ## Favorite Voices ### Marking Favorites **Mark as Favorite:** 1. Find voice in list 2. Click star icon 3. Voice added to favorites 4. Star icon filled **Unmark Favorite:** 1. Find favorite voice 2. Click filled star icon 3. Voice removed from favorites 4. Star icon unfilled ### Using Favorites **Access Favorites:** * Filter to show favorites only * Favorites section in browser * Quick access to preferred voices * Personal voice library **Benefits:** * Save time on selection * Consistent voice usage * Organized preferences * Easy access ## Voice Selection Best Practices ### Matching Voice to Content **Formal Content:** * Use Narrator style * Professional voice * Clear pronunciation * Consistent delivery **Casual Content:** * Use Conversational style * Friendly voice * Natural delivery * Engaging tone **Educational Content:** * Clear, articulate voice * Moderate pace * Professional but approachable * Easy to understand **Marketing Content:** * Energetic voice * Expressive delivery * Engaging tone * Memorable voice ### Language Considerations **Language Matching:** * Match voice language to text language * Use appropriate dialect * Consider audience dialect preference * Ensure language compatibility **Dialect Selection:** * Choose dialect your audience understands * Consider regional preferences * Use neutral dialect if unsure * Test with sample audience ### Voice Consistency **Series Content:** * Use same voice throughout * Mark as favorite for easy access * Maintain voice consistency * Create voice guidelines **Brand Voice:** * Select voice that matches brand * Use consistently across content * Document voice selection * Train team on voice choice ## Troubleshooting ### Voice Not Available **Issue:** Voice doesn't appear in list **Solutions:** * Clear filters * Check search terms * Verify voice availability * Refresh voice list ### Preview Not Working **Issue:** Voice preview doesn't play **Solutions:** * Check audio settings * Try different voice * Refresh page * Check browser audio ### Voice Selection Issues **Issue:** Cannot select voice **Solutions:** * Verify voice is available * Check permissions * Try different voice * Refresh interface ## Next Steps * **[Creating Jobs](./creating-jobs)** - Learn how to create TTS jobs * **[Voice Controls](./voice-controls)** - Adjust voice settings * **[Managing Jobs](./managing-jobs)** - Organize your TTS jobs * **[Overview](./overview)** - Learn about Text to Speech features ## Related Documentation Learn how to create TTS jobs Adjust voice settings and controls Organize and manage your TTS jobs Learn about Text to Speech features # Account Creation Source: https://docs.tryhamsa.com/overview/account-settings/account-creation Learn how to create and set up your account ## Overview When creating an account, you can choose between email/password registration or social login (Google, Microsoft). The account creation process differs slightly depending on your chosen method. ## Email/Password Registration ### Registration Process **Step-by-Step Process:** 1. **Navigate to Registration** * Go to the registration/signup page * Click "Sign Up" or "Create Account" link 2. **Enter Personal Information** * **First Name**: Enter your first name (required) * **Last Name**: Enter your last name (required) * Both fields are required and validated 3. **Enter Account Details** * **Email**: Enter your email address (required) * **Password**: Create a password (required) * **Confirm Password**: Re-enter password to confirm (required) 4. **Password Requirements** * Minimum 8 characters * Must contain at least one uppercase letter (A-Z) * Must contain at least one lowercase letter (a-z) * Must contain at least one number (0-9) * Must contain at least one special symbol (e.g., !@#\$%^&\*) * Must match in confirmation field * Real-time validation displayed 5. **Submit Registration** * Click **"Continue"** or **"Sign Up"** button * Account is created * You're redirected to email verification page 6. **Email Verification** * Check your email for verification link * Click the verification link * Account is activated * You can now log in ### Registration Validation * All fields are validated in real-time * Email must be valid format * Password must meet requirements * Confirmation must match password * Form cannot be submitted if invalid ## Social Login Registration ### Supported Providers * **Google**: Sign in with Google account * **Microsoft**: Sign in with Microsoft account ### Registration Process **Step-by-Step Process:** 1. **Navigate to Registration** * Go to the registration/signup page * Locate social login buttons 2. **Choose Provider** * Click **"Google"** or **"Microsoft"** button * You're redirected to provider's authentication page 3. **Authenticate with Provider** * Sign in with your Google or Microsoft account * Grant permissions if prompted * You're redirected back to the platform 4. **Account Created** * Account is created automatically * Email is automatically verified * You're logged in immediately * No password is set by default ### Post-Social Login Setup After signing up with social login: * **No Password Set**: You don't have a password initially * **Social Login Only**: You can only log in using social login * **Set Password (Optional)**: You can set a password later using "Forgot Password" (Security Settings requires a password to be set first) * **Email Verified**: Your email is automatically verified * **Full Access**: You have full access to all features After signing up with social login, you can set a password at any time using the "Forgot Password" feature on the login page. Once you've set your first password, you can then use Security Settings to update it. This allows you to log in with email/password in addition to social login. ## Related Documentation Account Settings overview Learn about password management and security Learn about account authentication and login # Notification Settings Source: https://docs.tryhamsa.com/overview/account-settings/notification-settings Control email notification preferences ## Overview The Notifications section allows you to control which email notifications you receive from the platform. You can customize notifications for job status updates and credit/billing information. ## Notification Categories ### Job Status Emails Get notified about the status of your tasks and jobs: **Job Ready** * Receive notifications when your job is completed successfully * Includes job completion notifications * Default: Enabled * Toggle on/off with switch **Job Failed** * Receive notifications when your job fails * Includes error notifications and failure alerts * Default: Enabled * Toggle on/off with switch ### Credit & Billing Emails Manage your billing and payment notifications: **Low Balance Alert** * Get warned when your account balance is running low * Helps prevent service interruptions * Default: Enabled * Toggle on/off with switch **Promotional Credit** * Receive notifications about promotional credits and offers * Marketing and promotional content * Default: Disabled * Toggle on/off with switch ## Managing Notifications ### Step-by-Step Process 1. **Navigate to Notifications Section** * Go to Account Settings * Click on "Notifications" tab or section 2. **Review Notification Options** * See all available notification types * Read descriptions for each notification * Understand what each notification covers 3. **Toggle Notifications** * Click the switch to enable/disable notifications * Changes apply immediately * Success message confirms update * No save button needed (changes are instant) 4. **Monitor Settings** * Settings are saved automatically * Changes apply to future notifications * Current notification preferences displayed * Settings persist across sessions ### Notification Behavior * Changes apply immediately * No need to save (auto-saved) * Success toast confirms each change * Settings apply to all future notifications * Previous notifications are not affected ## Troubleshooting ### Problem: Notifications not toggling **Solutions:** * Check network connection * Try toggling again * Refresh page and try again * Check for error messages ### Problem: Not receiving expected notifications **Solutions:** * Verify notification is enabled in settings * Check email spam/junk folder * Verify email address is correct * Review notification preferences ## Related Documentation Account Settings overview Manage your personal and company information Manage passwords and account security # Overview Source: https://docs.tryhamsa.com/overview/account-settings/overview Manage your profile, security, and notification preferences ## Overview Account Settings allows you to manage your personal information, security preferences, and email notification settings. These settings are shared across both the Agents Platform and Media Platform, providing a unified account management experience. All account settings are applied globally across both platforms. Changes to your profile, security, or notifications affect your entire account, regardless of which platform you're using. ## Accessing Account Settings ### Navigation To access Account Settings: 1. Click on your **user profile icon** in the top-right corner 2. Select **"Account Settings"** or **"Settings"** from the dropdown menu 3. The Account Settings page opens with three main sections: * **Profile**: Personal and company information * **Security**: Password management * **Notifications**: Email notification preferences ### Settings Sections The Account Settings page is organized into three main sections, each accessible via tabs or navigation: * **Profile**: Update personal and company information * **Security**: Manage password and security settings * **Notifications**: Control email notification preferences ## Settings Synchronization ### Cross-Platform Settings All account settings are shared across platforms: * **Profile Information**: Same profile on Agents Platform and Media Platform * **Security Settings**: Same password and security settings * **Notifications**: Same notification preferences Changes in one platform reflect in the other, providing a unified account management experience. ### Settings Persistence * Settings are stored in your account * Persist across sessions and devices * Synchronized across platforms * Backed up securely * Settings available immediately after login * Updates reflect in real-time ## Related Documentation Manage your personal and company information Manage passwords and account security Control email notification preferences Learn how to create and set up your account Learn about account authentication and login Manage your API keys for platform access # Profile Settings Source: https://docs.tryhamsa.com/overview/account-settings/profile-settings Manage your personal and company information ## Overview The Profile section allows you to manage your personal and company information. This information is used across the platform and may be displayed in various places. ## Profile Information ### Personal Information **First Name** (Required) * Your first name * Minimum: 1 character * Cannot be empty or whitespace only * Used for personalization and identification **Last Name** (Required) * Your last name * Minimum: 1 character * Cannot be empty or whitespace only * Used for personalization and identification ### Company Information **Company Name** (Optional) * Your company or organization name * Free text field * Used for organization identification * Optional but recommended for business accounts **Company Size** (Optional) * Size category of your company * Options: * Less than 10 (Small Company) * 10 - 49 (Medium Company) * 50-249 (Large Company) * More than 250 (Enterprise) * Used for analytics and support purposes * Optional selection **Website** (Optional) * Your company website URL * Must be a valid URL format (if provided) * Can be left empty * Optional field ## Updating Profile ### Step-by-Step Process 1. **Navigate to Profile Section** * Go to Account Settings * Click on "Profile" tab or section 2. **Edit Information** * Modify any fields you want to update * Required fields (First Name, Last Name) must be filled * Optional fields can be left empty 3. **Review Changes** * Check all entered information * Ensure required fields are completed * Verify URL format if website is provided 4. **Save Changes** * Click **"Update Profile"** button * Changes are saved immediately * Success message confirms update * Profile information updates across platforms ### Form Validation * First Name and Last Name are required * Fields cannot contain only whitespace * Website must be a valid URL (if provided) * Form shows validation errors in real-time ### Update Behavior * Changes apply immediately * Updates reflected across all platforms * No logout/login required * Sidebar and profile displays update automatically ## Troubleshooting ### Problem: Cannot update profile **Solutions:** * Check required fields are filled * Verify no validation errors * Ensure website URL is valid format * Try refreshing page and updating again ### Problem: Changes not saving **Solutions:** * Check network connection * Verify form is valid * Look for error messages * Try again after page refresh ## Related Documentation Account Settings overview Manage passwords and account security Control email notification preferences # Security Settings Source: https://docs.tryhamsa.com/overview/account-settings/security-settings Manage passwords and account security ## Overview The Security section allows you to manage your account password. You can update your existing password for enhanced security. If you signed up with social login and don't have a password yet, you must first set one using the "Forgot Password" option on the login page. If you signed up using social login (Google or Microsoft) and want to enable email/password login, you must use the "Forgot Password" option on the login page to set your first password. After setting your first password, you can use Security Settings to update it. ## Password Management ### Setting a Password for Social Login Users If you signed up using social login (Google, Microsoft), you cannot set a password directly from Security Settings initially. You must first set a password using the "Forgot Password" flow, after which you can use Security Settings to update your password. **Using Forgot Password to Set Your First Password** To set your first password after signing up with social login: 1. **Go to Login Page** * Navigate to the login page * Click **"Forgot Password"** link (next to the password field) 2. **Enter Your Email** * Enter the email address associated with your account * Click **"Submit"** button * A password reset email is sent to your address 3. **Check Your Email** * Open the password reset email * Click the reset link in the email * You'll be redirected to the password reset page 4. **Set Your Password** * Enter your new password * Confirm your new password * Click **"Reset Password"** button * Password is set successfully * You'll be redirected to the login page Social login users must use the "Forgot Password" option to set their first password. Once a password is set, you can use Security Settings to update your password in the future. Social login users cannot set a password directly from Security Settings until they have first set a password using the "Forgot Password" flow. After setting your first password through "Forgot Password", you can then use Security Settings to update it. ### Updating an Existing Password Once you have set a password (either through "Forgot Password" for social login users, or during email/password registration), you can update it using Security Settings: 1. **Navigate to Security Section** * Go to Account Settings * Click on "Security" tab or section 2. **Enter Current Password** * Enter your current password * Required for security verification 3. **Enter New Password** * Enter your new desired password * Confirm new password * Must meet password requirements 4. **Password Requirements** * Minimum 8 characters * Must contain at least one uppercase letter (A-Z) * Must contain at least one lowercase letter (a-z) * Must contain at least one number (0-9) * Must contain at least one special symbol (e.g., !@#\$%^&\*) * New password must be different from current * Must match in both confirmation fields 5. **Save Changes** * Click **"Update Password"** button * Password is updated successfully * You'll need to use the new password for future logins ## Forgot Password Flow ### Overview The Forgot Password feature allows you to reset your password if you've forgotten it, or set a password if you signed up with social login and don't have one yet. ### Requesting Password Reset **Step-by-Step Process:** 1. **Navigate to Login Page** * Go to the login page * Locate the "Forgot Password" link next to the password field 2. **Click Forgot Password** * Click the **"Forgot Password"** link * You're redirected to the forgot password page 3. **Enter Email Address** * Enter the email address associated with your account * The same email used for social login or email registration * Click **"Submit"** button 4. **Password Reset Email Sent** * A password reset email is sent to your address * Success message confirms email was sent * Check your inbox (and spam folder if needed) ### Resetting Password **Step-by-Step Process:** 1. **Check Your Email** * Open the password reset email * Look for the reset link * Email contains a secure token link 2. **Click Reset Link** * Click the password reset link in the email * Link is valid for a limited time * You're redirected to the password reset page 3. **Enter New Password** * Enter your new password in "New Password" field * Confirm password in "Confirm Password" field * Both fields must match 4. **Password Requirements** * Minimum 8 characters * Must contain at least one uppercase letter (A-Z) * Must contain at least one lowercase letter (a-z) * Must contain at least one number (0-9) * Must contain at least one special symbol (e.g., !@#\$%^&\*) * Must match in both fields * Real-time validation displayed 5. **Submit Reset** * Click **"Reset Password"** button * Password is reset successfully * Success message confirms reset * You're automatically redirected to the login page ### Cooldown and Rate Limiting The system implements cooldown periods to prevent abuse: **Cooldown Periods:** * **First request**: Immediate (no cooldown) * **Second request**: 1 minute wait * **Third request**: 5 minutes wait * **Fourth+ requests**: 15 minutes wait * **After 5 attempts**: Button is disabled **Cooldown Behavior:** * Cooldown timer displays remaining time * Button shows countdown or disabled state * Prevents excessive password reset requests * Resets after cooldown period expires After 5 password reset attempts, the "Forgot Password" feature is temporarily disabled. Wait for the cooldown period to expire or contact support if you need immediate assistance. ## Password Requirements ### Minimum Requirements * **Length**: At least 8 characters * **Uppercase Letter**: At least one uppercase letter (A-Z) * **Lowercase Letter**: At least one lowercase letter (a-z) * **Number**: At least one number (0-9) * **Special Character**: At least one special symbol (e.g., !@#\$%^&\*) * **Confirmation**: Must match in both password fields ### Security Best Practices * Use a strong, unique password * Don't reuse passwords from other accounts * Consider using a password manager * Change password periodically * Don't share your password with anyone ## Password Form Behavior ### For Users Without Password * Only "Set Password" and "Confirm Password" fields shown * Current password field hidden * Button labeled "Set Password" * Description explains setting up password for email/password login ### For Users With Password * Current password field shown (required) * "New Password" and "Confirm Password" fields shown * Button labeled "Update Password" * Description explains updating password for security ### Form Validation * Real-time validation as you type * Requirements displayed below password field * Confirmation must match new password * Current password required for updates * Form cannot be submitted if invalid ## Troubleshooting ### Problem: Cannot set password **Solutions:** * Verify password meets all requirements (8+ characters, uppercase, lowercase, number, special symbol) * Ensure confirmation matches * Check for validation errors * Try a different password ### Problem: Cannot update password **Solutions:** * Verify current password is correct * Check new password meets requirements * Ensure confirmation matches new password * Try again with correct current password ### Problem: Password requirements not clear **Solutions:** * Minimum 8 characters required * Must include at least one uppercase letter (A-Z) * Must include at least one lowercase letter (a-z) * Must include at least one number (0-9) * Must include at least one special symbol (e.g., !@#\$%^&\*) * Confirmation must match exactly * Requirements displayed below password field ### Problem: Forgot Password not working **Solutions:** * Check cooldown timer (may need to wait) * Verify email address is correct * Check spam/junk folder for reset email * Wait for cooldown period if you've made multiple requests * Contact support if disabled after 5 attempts ### Problem: Reset link expired or invalid **Solutions:** * Reset links expire after a period of time * Request a new password reset * Use the most recent reset email * Check that you're using the correct link ## Related Documentation Account Settings overview Manage your personal and company information Control email notification preferences Learn how to create and set up your account # Authentication Source: https://docs.tryhamsa.com/overview/auth To use the transcription API, you need to authenticate your requests.     ## Authetication: ### Create an Account On Hamsa Dashboard:

Click here to create an account on Hamsa using Hamsa Agents platform

Click here to create an account on Hamsa using Hamsa Media platform

  • First, you need to create an account from the link in the above card.
  • After creating an account, you will recieve an email directs you to the login page.
  • Now, you can sign in to your account using the same email and password you used.
  • You can use Continue with Google option to signup with using Google Auth.
  • ### Authentication Steps in Picutures:
  • Signing Up - Creating an account
  • hamsa signup home button hamsa signup next component
  • Sign In - Log in to your account
  • hamsa signin page
  • Continue with Google- Signup - Login using Google Auth
  • hamsa signin page
  • Continue with Microsoft- Signup - Login using Microsoft Auth
  • hamsa signin page # Speech to Text Source: https://docs.tryhamsa.com/overview/capabilities/speech-to-text Transcribe Arabic and English speech into accurate text Hamsa Speech to Text (STT) accurately transcribes Arabic speech across multiple dialects into text with word-level timestamps and speaker identification. ## What you can do * Transcribe Arabic media content, podcasts, and videos * Generate subtitles for Arabic video content * Create searchable text from Arabic audio recordings * Enable real-time transcription for voice agents and live calls * Document Arabic meetings and interviews ## Models | Model | Best For | Latency | | ---------------- | ----------------------------------- | --------------------- | | **STT Standard** | Batch transcription, high accuracy | Optimized for quality | | **STT Realtime** | Live calls, voice agents, streaming | \~150-250ms | Compare models and see detailed specifications ## Key features * **Dialect recognition**: Automatic detection and transcription of Arabic dialects * **Word-level timestamps**: Precise timing for each transcribed word; the transcription API returns word-level data (word text plus start/end times) in each transcript segment so you can build word highlight or karaoke-style experiences * **Word highlight during playback**: In the Media Platform, the word currently being spoken is highlighted in sync with the audio or video; you can also click a word to jump to that point in the media * **Speaker diarization**: Identify different speakers in multi-speaker audio * **Code-switching**: Handle mixed Arabic-English speech naturally ## Word highlight during playback The transcription API returns **word-level data** in each transcript segment: each word includes its text plus start and end timestamps (in seconds). This enables two things: * **In the Media Platform**: When you open a transcription and play the audio or video, the word currently being spoken is highlighted in sync with playback. You can also click any word in the transcript to seek the media to that position. * **Via the API**: Your application receives the same word-level timestamps in the transcript/segment response, so you can build karaoke-style highlighting, click-to-seek, or other experiences that follow the speech. ## Supported languages * **Arabic dialects**: Egyptian, Gulf, Levantine, North African, Iraqi, Yemeni, Modern Standard Arabic * **English**: US English ## Get started Complete guide to Speech to Text features and integration Get started with STT in minutes Use STT through the web interface Technical API documentation # Text to Speech Source: https://docs.tryhamsa.com/overview/capabilities/text-to-speech Convert text into natural-sounding Arabic and English speech Hamsa Text to Speech (TTS) converts written text into natural-sounding audio with proper Arabic pronunciation, intonation, and support for multiple dialects. ## What you can do * Generate voiceovers for Arabic media content and advertisements * Create accessible audio versions of written Arabic content * Build real-time voice agents for customer service * Produce e-learning content with natural Arabic pronunciation ## Models | Model | Best For | Latency | | ---------------- | -------------------------------------- | ----------- | | **TTS Standard** | High-quality content, media production | \~300-500ms | | **TTS Realtime** | Voice agents, conversational AI | \~150-200ms | Compare models and see detailed specifications ## Supported languages * **Arabic dialects**: Egyptian, Gulf, Levantine, North African, Modern Standard Arabic * **English**: US English ## Get started Complete guide to Text to Speech features, voices, and integration Get started with TTS in minutes Use TTS through the web interface Technical API documentation # Voice Agents Source: https://docs.tryhamsa.com/overview/capabilities/voice-agents Build intelligent AI voice agents for phone calls in Arabic and English > Learn how to build, deploy, and scale AI voice agents with Hamsa. ## Overview Hamsa [Voice Agents Platform](/agents/introduction) enables you to build intelligent conversational AI that handles phone calls naturally in Arabic and English. Create voice agents that can understand multiple Arabic dialects, respond appropriately, and take actions based on conversation context. Your voice agents can: * Handle inbound and outbound phone calls automatically * Deploy on websites using our [Voice Agents SDK](https://www.npmjs.com/package/@hamsa-ai/voice-agents-sdk) * Understand and respond in English and multiple Arabic dialects * Access your company's knowledge base for accurate information * Execute actions through custom tools and API integrations * Transfer calls to human agents when needed * Collect and validate data from callers * Make intelligent decisions based on conversation flow Step-by-step guide for building voice agents in Hamsa Platform. Learn how to integrate voice agents into your application via API. ## Agent types Hamsa offers two distinct approaches for building voice agents: ### Single Prompt Agent Perfect for straightforward use cases with linear conversation flows. Simply write a prompt describing your agent's behavior, and it handles the conversation naturally. Simple, fast, and effective for basic customer support, lead qualification, and information gathering **Best for:** * Simple information gathering * Basic customer support * Appointment booking and reminders * Lead qualification * Quick prototypes and MVPs **Key features:** * Setup in minutes * Natural conversation flow * Knowledge base integration * Custom tools support * Webhook notifications ### Flow Agent Build sophisticated conversation flows with a visual node-based editor. Design complex multi-step processes with conditional logic, DTMF support, and advanced routing. Advanced workflows with 8 node types, conditional logic, visual debugging, and DTMF support **Best for:** * Multi-step processes with conditional logic * Complex customer service workflows * IVR menus and call routing * Advanced call transfers * Integration-heavy applications * DTMF data collection **Key features:** * Visual flow designer * 8 specialized node types * Advanced variable system * DTMF support (3 modes) * Agent-to-agent transfers * Real-time debugging ## Quick comparison | Feature | Single Prompt | Flow Agent | | --------------------- | ------------- | -------------------------- | | **Setup Time** | Minutes | Hours | | **Visual Design** | No | Yes | | **Conditional Logic** | Limited | Unlimited | | **DTMF Support** | No | Yes (3 features) | | **Variable System** | Basic | Advanced (16+ system vars) | | **Agent Transfer** | No | Yes | | **Call Routing** | Simple | Advanced | | **Best For** | Simple flows | Complex workflows | ## Platform capabilities ### Natural conversations in Arabic Built specifically for Arabic markets, Hamsa voice agents understand and respond naturally in multiple Arabic dialects: * **Dialect understanding**: Recognize Egyptian, Gulf, Levantine, North African, and other Arabic dialects * **Natural responses**: Generate contextually appropriate responses in the caller's dialect * **Code-switching**: Handle mixed Arabic-English conversations naturally * **Cultural context**: Understand cultural nuances and expressions specific to each region ### Knowledge Base integration Give your voice agents access to your company's information: **Document Upload** * Support for PDF, DOCX, TXT, HTML, and EPUB files * Up to 21MB per file * Automatic content extraction and indexing **Website Scraping** * Enter any domain URL to scan for content * Real-time sitemap streaming with progress updates * URLs grouped by subdomain for easy selection * Select up to 100 URLs per knowledge base item * Add custom URLs not found in sitemap * Individual URL scraping status tracking **Text Content** * Add custom text entries (50-10,000 characters) * Perfect for FAQs, policies, and quick reference content **Agent Integration** * Real-time information retrieval during calls * Automatic relevance ranking * Activate/deactivate items per agent Explore knowledge base features ### Custom Tools & integrations Connect your voice agents to any external system: * REST API integrations * Web client-side tools * Custom function calling * Database queries * CRM integrations * Payment processing * Appointment scheduling systems Explore tools and integrations ### Telephony features Enterprise-grade telephony features: * **Inbound calls**: Assign phone numbers to agents for incoming calls * **Batch calls**: Launch automated calling campaigns * **Call forwarding**: Transfer calls to human agents or other systems * **DTMF support**: Handle keypad input for IVR menus (Flow Agents) * **Call recording**: Automatic recording and storage of all calls * **Real-time monitoring**: Monitor active calls in real-time Explore telephony features ### Monitoring & analytics Comprehensive monitoring and analytics: * **Live call monitoring**: Watch active calls in real-time with live transcripts * **Call history**: Complete records of all conversations * **Performance metrics**: Track success rates, call duration, and outcomes * **Satisfaction scores**: Monitor customer satisfaction trends * **Conversation analysis**: Review transcripts and identify improvement areas * **System logs**: Debug with detailed execution logs Explore dashboard and monitoring ## Use cases ### Customer support Handle common customer inquiries automatically in Arabic. Provide 24/7 support with agents that understand context and can escalate to humans when needed. **Example applications:** * Answer FAQs about products and services * Check order status and account information * Handle basic troubleshooting * Schedule callbacks with human agents ### Lead qualification Qualify leads automatically through natural conversations in Arabic. Collect information, assess interest levels, and route qualified leads to sales teams. **Example applications:** * Initial lead screening * Information gathering * Appointment scheduling * Lead scoring and routing ### Appointment booking Automate appointment scheduling for healthcare, services, or consultations. Handle booking, rescheduling, and reminders in Arabic. **Example applications:** * Medical appointment scheduling * Service booking and confirmation * Appointment reminders * Rescheduling and cancellations ### Surveys & feedback Conduct surveys and collect feedback through natural phone conversations in Arabic. Higher engagement than traditional IVR systems. **Example applications:** * Customer satisfaction surveys * Post-service feedback * Market research * Product feedback collection ### Payment reminders Send automated payment reminders with natural conversations. Handle common questions and provide payment options. **Example applications:** * Bill payment reminders * Subscription renewal reminders * Payment plan negotiations * Payment confirmation ## Best practices ### Designing effective prompts For Single Prompt Agents: * Be specific about the agent's role and objectives * Provide clear examples of desired behavior * Define boundaries and escalation rules * Include cultural and dialectal considerations * Test with various scenarios Prompt engineering guide ### Building robust flows For Flow Agents: * Start with a clear flow diagram on paper * Use Router nodes for complex decision logic * Implement proper error handling * Test all possible paths * Use variables efficiently * Add fallback options for unexpected inputs Flow Agent best practices ### Testing thoroughly Before deployment: * Test with different Arabic dialects * Test edge cases and unexpected inputs * Verify tool and API integrations * Check knowledge base responses * Test call transfers and escalations * Monitor performance metrics Testing guide ## Getting started Decide between Single Prompt or Flow Agent based on complexity Set up voice, language, LLM model, and behavior settings Write prompts or design visual flow with nodes Connect knowledge bases, tools, and webhooks Test in browser and via phone with different scenarios Assign phone numbers, launch campaigns, and monitor performance ## FAQ Choose Single Prompt Agent for simple, linear conversations (lead qualification, basic support). Choose Flow Agent for complex workflows requiring conditional logic, DTMF support, or multi-step processes (IVR systems, advanced routing). Yes, both agent types automatically understand and respond in multiple Arabic dialects. The system detects the caller's dialect and responds appropriately. Use custom tools to integrate with any REST API, webhooks for event notifications, and the Voice Agents API to programmatically manage agents. See our [integration guides](/developers/guides/api-integration) for details. Flow Agents support call transfers to human agents or other AI agents. Use the Transfer Call node to forward calls to external numbers, or the Transfer to Agent node for agent-to-agent handoffs with conditional routing. Single Prompt Agents do not support call transfers. Use the Dashboard to monitor live calls, view call history, analyze performance metrics, and track customer satisfaction. All conversations are recorded and transcribed for review. Hamsa supports leading LLM providers including OpenAI (GPT-4.1, GPT-5), Gemini (2.5-Pro, 2.5-Flash), Groq, and DeepMyst. Choose the model that best fits your use case and budget. See [LLM configuration](/overview/features/llm-configuration) for details. ## Next steps Quick start guide for building your first voice agent Learn about Single Prompt Agents Explore Flow Agent capabilities SDK for embedding voice agents in web apps # Create API Keys Source: https://docs.tryhamsa.com/overview/create-api-keys This page shows you how to use Hamsa Dashboard to create new API keys.    
    Click here to return to the Authentication page if you haven't crated an account yet.
    ## Create an API Key Once you logged in, please select the Create API Key button on the Dashboard page, or you can choose API keys tab and then choose Create API Key button as illustrated in the images below. Create API key from dashboard page Create API key from API key page Once you hit that button, a pop up will appear where you have two options:
  • First, you can set an API Key Name and Expiry Date
  • Second, you can set an API Key Name with No Expiry Date
  • Create API key pop up After creating the API key, You can now copy the API Key Identifier from Hamsa Dashboard and use it in the routes! Some API endpoints also require a **Project ID**. You can copy your Project ID from the project switcher in the top navigation bar of the dashboard. See [Projects Overview](/overview/projects/overview#finding-your-project-id) for details. Copy API kye

    ### *Happy Coding!* # Voice Cloning Source: https://docs.tryhamsa.com/overview/features/voice-cloning Create custom AI voices unique to your brand from audio samples ## Overview Voice Cloning allows you to create completely custom AI voices that perfectly match your brand identity, specific tone requirements, or unique vocal characteristics. Upload audio samples or record directly to generate an AI voice model that can be used across all your agents. **Voice Cloning Features:** * **Custom Voice Creation** - Build unique voices from audio samples * **Upload or Record** - Flexible input options (upload files or record in-browser) * **Multi-Language Support** - Create voices in English or Arabic * **Dialect Options** - Specify regional accents for Arabic voices * **Instant Preview** - Test your voice before finalizing * **Unlimited Voices** - Create as many custom voices as you need ## Why Use Voice Cloning Custom voice cloning enables powerful use cases: **Brand Consistency:** * Create a signature voice that represents your company * Ensure consistent voice across all customer interactions * Stand out from competitors using generic AI voices **Authenticity:** * Clone authorized voices (CEO, founder, brand ambassador) * Maintain authentic regional accents * Preserve specific vocal characteristics **Professional Quality:** * Match specific tone and style requirements * Create industry-specific voices (medical, legal, technical) * Control exact pronunciation and cadence **Flexibility:** * Create multiple voices for different departments or scenarios * Test different voice personalities * Update and refine voices as your brand evolves Voice cloning creates an AI model from your audio samples. The quality of your input audio directly impacts the quality of the generated voice. ## How Voice Cloning Works The voice cloning process is straightforward: 1. **Provide Audio Sample** - Upload an audio file or record directly 2. **Configure Details** - Set name, language, dialect, tags, and optional cover image 3. **Generate Preview** - Test how your voice sounds with sample text 4. **Create Voice** - Finalize and add to your voice library 5. **Use in Agents** - Select your custom voice like any library voice ### Processing Time * **Voice Creation:** 30-60 seconds * **Preview Generation:** 10-30 seconds * **Availability:** Immediate after creation ## Creating a Custom Voice ### Step 1: Voice Details **Name** (Required) * Give your voice a descriptive name * Examples: "Customer Service - Sarah", "Sales - Professional Male" * Max 100 characters * Helps identify voice in library **Description** (Optional) * Add context about the voice * Note use cases or characteristics * Internal reference only (not visible to customers) **Language** (Required) Choose the primary language: * **English** - For English-speaking markets * **Arabic** - For Arabic-speaking markets Select the language that matches your actual use case. This affects pronunciation, natural speech patterns, and overall voice quality. **Dialect** (Required for Arabic) For Arabic voices, select specific regional dialect: * Egyptian (EG) * Jordanian (JO) * Saudi Arabian (SA) * UAE (AE) * Gulf * Levantine * North African Choosing the correct dialect ensures natural pronunciation and helps your agent connect authentically with your target audience. **Voice Tags** (Required) Select exactly 2 tags - one from each category: **Gender:** * Male - Masculine voice * Female - Feminine voice **Style:** * Conversational - Natural, friendly tone * Narrator - Clear, articulate tone **Cover Image** (Optional) * Upload a visual representation (JPG, PNG) * Max size: 5 MB * Displays on voice card in library * Professional headshot or brand logo recommended ### Step 2: Input Audio You have two options for providing audio: #### Option A: Upload Audio File **Supported Formats:** * MP3, WAV, WebM, OGG, AAC, M4A, FLAC **Requirements:** * Max file size: 32 MB * Recommended duration: 30-90 seconds * Clear, noise-free audio * Natural speech with varied sentences **Upload Process:** 1. Click "Upload" tab 2. Drag and drop file or click to browse 3. Wait for upload completion 4. File validated automatically #### Option B: Record Voice Record directly in your browser: **Requirements:** * Duration: 3-9 seconds * Browser microphone access required * Format: WAV (automatic) **Recording Process:** 1. Click "Record" tab 2. Grant microphone permission 3. Click "Start Recording" 4. Speak naturally (2-3 sentences) 5. Click "Stop Recording" 6. Review recording 7. Re-record if needed **Recording Length Requirements:** * Minimum: 3 seconds (validation error if shorter) * Maximum: 9 seconds (recording stops automatically) * Recommended: 5-7 seconds for best results ### Step 3: Generate Preview Test your voice before finalizing: 1. Enter sample text (minimum 5 words) 2. Click "Generate Preview" 3. Wait for processing (10-30 seconds) 4. Listen to audio preview 5. Regenerate with different text if needed **Preview Text Examples:** ``` "Hello, thank you for calling. How can I help you today?" "Welcome to Acme Corporation. I'm here to assist with any questions." "Your order has been confirmed and will ship within two business days." ``` Use text that matches your actual agent scripts to hear how the voice will sound in real conversations. ### Step 4: Create Voice Once satisfied with the preview: 1. Click "Create" button 2. Wait for processing (30-60 seconds) 3. Voice added to "My Voices" library 4. Available immediately in all agents Custom voice created successfully! Find it in the "My Voices" tab. ## Audio Quality Guidelines ### Recording Environment **Ideal Environment:** * Quiet room with minimal echo * Closed windows and doors * No background noise (HVAC, fans, traffic) * Sound-dampening materials (curtains, furniture) **Avoid:** * Outdoor locations * Rooms with hard surfaces (echo) * Areas with background conversations * Near computers or electronics ### Microphone Selection **Good Options:** * USB condenser microphone * Noise-canceling headset * Dedicated podcasting microphone * Quality laptop built-in mic (in quiet space) **Poor Options:** * Phone speakerphone * Low-quality earbuds * Far-field microphones * Heavily compressed audio sources ### Audio Content **Include Variety:** * Questions and statements * Different emotions (friendly, professional, reassuring) * Various sentence lengths * Natural pauses and inflection * Varied pronunciation patterns **Avoid:** * Monotone speech * Reading lists or numbers only * Repetitive phrases * Shouting or whispering * Background music or sound effects The quality and variety of your audio sample directly determines the naturalness and versatility of your cloned voice. ## Managing Custom Voices ### Viewing Custom Voices 1. Navigate to "Voices" in sidebar 2. Click "My Voices" tab 3. All custom voices display here 4. Same features as library voices (preview, favorite, filter) ### Using Custom Voices Custom voices work identically to library voices: **In Single Prompt Agents:** 1. Open agent Voice Settings 2. Click "Select Voice" 3. Navigate to "My Voices" tab 4. Select your custom voice **In Flow Agents:** * Available in global voice settings * Can be used in node-level overrides * Appears in all voice selection menus ### Editing Voice Details Update voice information: * Change voice name * Update description * Modify tags * Replace cover image Editing voice details does not require re-processing. Changes are instant. ### Deleting Custom Voices Deleting a custom voice is permanent and cannot be undone. **Before Deleting:** * Remove voice from all agents using it * Save/export audio sample if you want to recreate later * Confirm no other team members are using it **Deletion Process:** 1. Find voice in "My Voices" tab 2. Click voice actions menu (⋮) 3. Select "Delete Voice" 4. Confirm deletion 5. Voice removed permanently **Impact on Agents:** * Agents using deleted voice will show error * Must select new voice for affected agents * Previous call recordings remain accessible ## Voice Cloning Best Practices ### Sample Selection Strategy **For Customer Service:** * Friendly, helpful tone * Clear enunciation * Moderate, comfortable pace * Warm, welcoming inflection **For Sales:** * Confident, enthusiastic energy * Engaging and personable * Natural variation in pace * Professional but approachable **For Technical Support:** * Clear, methodical pace * Patient, reassuring tone * Precise pronunciation * Calm demeanor **For Announcements:** * Authoritative, clear delivery * Professional tone * Consistent pacing * Formal style ### Multi-Voice Strategy Create specialized voices for different scenarios: **Example: Customer Service Department** ``` Voice 1: "Customer Service - Friendly Female" - Tags: Female, Conversational - Use: General inquiries, warm greetings Voice 2: "Customer Service - Professional Male" - Tags: Male, Narrator - Use: Account information, formal communications Voice 3: "Customer Service - Calm Female" - Tags: Female, Conversational - Use: Complaint handling, de-escalation ``` ### Testing Custom Voices **Comprehensive Testing Process:** 1. **Preview Testing** - Generate multiple TTS previews with varied scripts 2. **Agent Integration** - Create test agent with your voice 3. **Script Testing** - Test with actual conversation flows 4. **Team Review** - Get feedback from colleagues 5. **A/B Testing** - Compare with library voices 6. **Live Pilot** - Deploy to small percentage of calls first 7. **Customer Feedback** - Monitor customer reactions **Quality Checklist:** * [ ] Pronunciation is clear and natural * [ ] Pace is appropriate for use case * [ ] Tone matches brand personality * [ ] No robotic or artificial qualities * [ ] Handles varied sentence types well * [ ] Emotional range is appropriate * [ ] Consistent quality across different texts * [ ] Regional pronunciation is accurate (if applicable) ## Common Issues and Solutions ### "Recording too short" Error **Problem:** Recording is less than 3 seconds **Solutions:** * Record longer sample (5-7 seconds recommended) * Speak 2-3 complete sentences * Don't rush through the recording * Include natural pauses ### "Audio file too large" Error **Problem:** File exceeds 32 MB limit **Solutions:** * Compress audio file using audio editor * Convert to MP3 format with reasonable bitrate * Trim unnecessary silence at beginning/end * Use online audio compression tools ### "Preview generation failed" Error **Problem:** TTS preview won't generate **Possible Causes:** * Audio quality too low * Audio sample too short or too long * Excessive background noise * Temporary server processing issue **Solutions:** * Upload different, higher-quality audio sample * Ensure recording environment is quiet * Check file format is supported * Verify file isn't corrupted * Try again (may be temporary issue) ### Voice Sounds Robotic or Unnatural **Problem:** Generated voice lacks natural quality **Common Causes:** * Poor audio sample quality * Background noise in recording * Insufficient vocal variation * Overly monotone source audio * Very short sample duration **Solutions:** * Re-record in quieter environment * Use better quality microphone * Include more natural speech variation * Speak with authentic inflection and emotion * Provide longer audio sample (if using upload) ### Can't Find Custom Voice **Problem:** Created voice doesn't appear in agent settings **Solutions:** * Check specifically in "My Voices" tab * Refresh browser page * Verify voice creation completed successfully * Confirm you're in correct project * Check if voice was accidentally deleted ## Use Cases and Examples ### Brand Voice Consistency **Scenario:** National retail chain **Goal:** Consistent voice across all locations **Solution:** 1. Clone authorized brand representative's voice 2. Create custom voice with approved characteristics 3. Use across all agent instances 4. Ensure 100% brand consistency ### Regional Market Targeting **Scenario:** Middle East e-commerce **Goal:** Connect authentically with GCC customers **Solution:** 1. Clone native Gulf Arabic speaker 2. Select UAE or Saudi dialect 3. Ensure regional pronunciation patterns 4. Build trust through authentic accent ### Multi-Department Strategy **Scenario:** Large enterprise **Goal:** Different voices for different departments **Solution:** 1. Sales: Energetic, engaging voice 2. Support: Calm, helpful voice 3. Billing: Professional, clear voice 4. Executive: Authoritative, trustworthy voice ### Legacy Voice Preservation **Scenario:** Replacing voice actor **Goal:** Maintain consistency after personnel change **Solution:** 1. Clone original voice actor (with permission) 2. Create AI voice model 3. Transition seamlessly to AI 4. Preserve customer familiarity ## Technical Specifications ### File Specifications **Upload:** * Max size: 32 MB * Formats: MP3, WAV, WebM, OGG, AAC, M4A, FLAC * Recommended duration: 30-90 seconds * Sample rate: 16kHz or higher recommended **Recording:** * Duration: 3-9 seconds * Format: WAV (automatic) * Sample rate: Browser default * Bitrate: Automatic ### Processing Specifications * Voice creation time: 30-60 seconds * Preview generation: 10-30 seconds * Storage: Permanent (until manually deleted) * Usage: Unlimited across all agents ### Limitations **Per Account:** * Unlimited custom voices * 32 MB max file size per upload * 3-9 seconds for direct recording * 5 MB max cover image size ## Advanced Features ### Instant Voice Enhancement (Beta) Premium feature for improved voice quality: **Features:** * Automatic background noise removal * Voice clarity enhancement * Consistency optimization * Better results with imperfect recordings Instant Voice Enhancement is a premium beta feature. Contact sales for access. ### Voice Versioning Maintain multiple versions of the same voice: **Use Case:** Test improvements without losing original **Process:** 1. Create new voice with updated audio sample 2. Use naming convention (e.g., "Sales Voice v2") 3. Test new version in parallel 4. Switch agents when ready 5. Keep old version as backup ## Related Documentation Browse pre-built AI voices from our library Configure voice in Single Prompt Agents Set up voices in Flow Agents Test your custom voice in real call scenarios # Voices Source: https://docs.tryhamsa.com/overview/features/voices Select from a diverse library of AI voices to give your agents the perfect personality and tone ## Overview Give your AI agents a unique voice that represents your brand. Choose from our extensive library of over 100 professional AI voices across multiple languages, dialects, and styles, or create custom voices tailored to your specific needs. **Voice Features:** * **100+ Professional Voices** - Diverse selection of high-quality AI voices * **Multiple Languages** - English and Arabic support * **Regional Dialects** - Authentic accents for your target market * **Voice Styles** - Conversational and narrator options * **Custom Voice Cloning** - Create unique voices from your own audio * **Easy Integration** - Select and preview voices directly in agent settings ## Why Voice Selection Matters Your agent's voice is often the first impression customers have of your business. The right voice can: * **Build Trust** - Professional, clear voices establish credibility * **Match Your Brand** - Align voice personality with brand identity * **Improve Engagement** - Natural, friendly voices keep customers engaged * **Enhance Understanding** - Clear pronunciation improves comprehension * **Target Markets** - Regional dialects connect with local audiences Voice selection is one of the most important decisions when creating an AI agent. Take time to preview multiple options and test voices in real scenarios. ## Voice Library ### Available Voices Our voice library includes: **Languages:** * **English** - Multiple accents (US, UK, Australian, etc.) * **Arabic** - Regional dialects (Egyptian, Gulf, Levantine, etc.) **Gender Options:** * Male voices * Female voices **Voice Styles:** * **Conversational** - Natural, friendly tone for customer interactions * **Narrator** - Clear, articulate tone for announcements and information ### Voice Organization Voices are organized into tabs for easy access: 1. **All Voices** - Browse the complete library 2. **Favorite Voices** - Quick access to your preferred voices 3. **Currently Used** - Voices recently used in your agents 4. **My Voices** - Custom voices you've created ## Voice Selection Process ### Browsing and Filtering Find the perfect voice using our filtering system: **Filter by:** * Gender (Male, Female, Both) * Language (English, Arabic, Both) * Style (Conversational, Narrator, Both) * Dialect (Arabic regions only) **Search:** * Search by voice name * Real-time results as you type ### Previewing Voices Before selecting a voice: 1. Click the play button on any voice card 2. Listen to the audio sample 3. Compare multiple voices side-by-side 4. Test with your actual use case in mind Preview at least 3-5 voices before making your final selection. What sounds good on first listen might not be ideal for your specific use case. ### Selecting a Voice **For Single Prompt Agents:** 1. Open agent configuration 2. Navigate to Voice Settings section 3. Click "Select Voice" 4. Browse, filter, and preview voices 5. Click on a voice card to select it **For Flow Agents:** * Set a global voice for the entire flow * Override voice at the node level for specific scenarios * Use different voices for different conversation stages ## Voice Characteristics ### Understanding Voice Styles **Conversational Voices:** * Natural speaking patterns * Friendly and engaging tone * Best for: Customer service, sales, support calls * Sounds like a helpful person having a conversation **Narrator Voices:** * Clear, articulate delivery * Professional and authoritative tone * Best for: Announcements, instructions, information delivery * Sounds like a professional presenter ### Regional Dialects (Arabic) Match your voice to your target market: **Egyptian Arabic** * Widely understood across Middle East * Great for broad regional appeal * Common in media and entertainment **Gulf Arabic (Saudi, UAE)** * Preferred in GCC markets * Professional business tone * Regional authenticity **Levantine (Jordan, Syria, Lebanon)** * Clear, widely understood * Formal and informal options * Regional connection Selecting the correct dialect ensures natural pronunciation and helps your agent connect authentically with your target audience. ## Voice Customization Beyond selecting a library voice, you can customize: **Voice Speed:** * Adjust speaking pace * Slower for clarity * Faster for efficiency **Voice Settings:** * Temperature control * Stability settings * Language-specific options **Custom Voices:** * Clone your own voice * Create brand-specific voices * Upload audio samples or record directly ## Managing Favorites ### Why Use Favorites * **Quick Access** - Find your preferred voices instantly * **Team Consistency** - Share favorite voice IDs with team members * **Easy Comparison** - Compare top choices in one place * **Organized Selection** - Build curated collections for different use cases ### Adding Favorites 1. Find a voice you like in the library 2. Click the star icon on the voice card 3. Voice is added to your "Favorite Voices" tab Create a curated collection of 3-5 favorite voices for different scenarios: customer service, sales, support, announcements. ## Voice Cloning Create completely custom voices unique to your brand: ### Custom Voice Features * **Upload Audio** - Use pre-recorded voice samples * **Record Directly** - Record voice samples in-browser * **Multiple Languages** - Support for English and Arabic * **Instant Preview** - Generate TTS preview before finalizing * **Full Integration** - Use custom voices just like library voices ### Use Cases for Custom Voices **Brand Voice Consistency:** * Clone your CEO's or founder's voice * Create a signature brand voice * Maintain consistency across all customer touchpoints **Celebrity or Influencer:** * Use authorized voice cloning for brand partnerships * Create authentic voice experiences **Regional Authenticity:** * Clone voices with specific regional characteristics * Match exact accent requirements **Legacy Preservation:** * Maintain voice consistency when replacing voice actors * Preserve signature voices Custom voice cloning is available to all users. See the [Voice Cloning documentation](/overview/features/voice-cloning) for detailed instructions. ## Voice Settings in Agents ### Single Prompt Agents Voice settings include: * Voice selection from library or custom voices * Voice speed adjustment * Language configuration * Additional voice parameters ### Flow Agents More advanced voice options: * **Global Voice** - Default voice for entire flow * **Node-Level Override** - Different voices for specific nodes * **Scenario-Based Voices** - Match voice to conversation context **Example Multi-Voice Flow:** ``` Welcome Node: Friendly female conversational voice Support Node: Professional male narrator voice Transfer Node: Calm, reassuring voice ``` ## Technical Details ### Voice IDs Every voice has a unique ID: * Used in API integrations * Programmatic agent configuration * Team sharing and documentation **Copy Voice Information:** 1. Click voice card menu (⋮) 2. Select "Copy ID" or "Copy Name" 3. Use in your integrations or documentation ### Voice Processing * **Selection Time** - Instant (no processing delay) * **Call Quality** - High-quality audio streaming * **Language Detection** - Automatic language matching * **Pronunciation** - Context-aware pronunciation ## Common Questions ### Can I use different voices in one agent? Yes, in Flow Agents you can set different voices for different nodes. This allows you to use specific voices for different conversation scenarios. ### How many voices can I favorite? Unlimited. Favorite as many voices as you need for your various use cases. ### Can I change an agent's voice after deployment? Yes, you can change an agent's voice at any time. The change takes effect immediately for new calls. ### Do voices support all languages? Each voice supports specific languages. English voices work with English text, and Arabic voices work with Arabic text. Always match voice language to your agent's conversation language. ### What happens if I delete a custom voice? If you delete a custom voice that's being used by an agent, that agent will show an error and you'll need to select a new voice. ## Related Documentation Create custom voices from your own audio samples Configure voice in Single Prompt Agents Set up voices in Flow Agents Test how your selected voice sounds in real calls # Introduction Source: https://docs.tryhamsa.com/overview/introduction Build powerful AI voice agents and leverage advanced media APIs with Hamsa # Welcome to Hamsa Hamsa helps you build intelligent voice solutions for the Arabic-speaking world. From AI voice agents that handle phone calls naturally, to speech recognition and synthesis optimized for Arabic dialects - we provide the tools you need. ## What can you build with Hamsa? Build AI agents that handle phone calls in Arabic and English Transcribe Arabic speech across multiple dialects Convert text into natural-sounding Arabic speech ## Get started Build your first integration in minutes Explore our TTS and STT models Set up authentication and API keys Understand key concepts and terminology ## Choose your path ### Platform Guides Use Hamsa through our web interfaces to build voice agents and process media. Build and deploy AI voice agents through our platform Process audio with TTS and STT through our web interface ### Developer Documentation Integrate Hamsa's capabilities into your applications via API. Get started with the Hamsa API Complete API documentation ## Why Hamsa? Built specifically for Arabic dialects with deep understanding of regional variations, code-switching, and cultural context Enterprise-grade reliability with low latency, high accuracy, and comprehensive monitoring Simple APIs, SDKs, and web interfaces - integrate in minutes, not weeks From simple text-to-speech to complex multi-step voice agents - build what you need ## Explore by capability Build AI-powered voice agents that handle phone calls naturally in Arabic and English. **What you can do:** * Create conversational AI for customer support * Automate appointment booking and reminders * Build lead qualification systems * Deploy IVR menus with natural language understanding Convert text into natural-sounding Arabic speech across multiple dialects. **What you can do:** * Generate voiceovers for media content * Create accessible audio versions of text * Power real-time voice applications * Build e-learning content with natural pronunciation Transcribe Arabic speech into text with word-level timestamps and speaker identification. **What you can do:** * Generate subtitles for Arabic videos * Transcribe meetings and interviews * Build voice-enabled applications * Create searchable audio archives ## Need help? Get help from our team # Limits and Usage Source: https://docs.tryhamsa.com/overview/limits-and-usage How plan credits, usage limits, and concurrency limits work across Hamsa services ## Overview Hamsa offers six plans: Free, Starter, Creator, Pro, Business, and Enterprise. Paid plans renew monthly — with a 15% discount when billed annually — and include a monthly credit allocation plus per-service usage limits. The Free plan works differently: it is a one-time credit grant, not a subscription. *** ## Plans and Credits Credits are consumed when using Hamsa services — Voice Agents, Speech to Text, and Text to Speech. | Plan | Credits | Description | | -------------- | -------------------- | --------------------------------------------- | | **Free** | 50 credits, one-time | For trying out the platform | | **Starter** | 100 credits/month | For hobbyists creating projects with AI audio | | **Creator** | 500 credits/month | For creators making premium content | | **Pro** | 5,000 credits/month | For creators ramping up their production | | **Business** | 20,000 credits/month | For rapidly scaling startups and publishers | | **Enterprise** | Custom | Volume-based discounts and custom terms | **The Free plan never renews.** Every new account gets 50 free credits to try Hamsa — granted once at signup, and you're never charged. When you're ready to build, pick a paid plan that renews monthly. Credits on paid plans **reset at the start of each billing cycle**. Unused credits do not roll over to the next month. ### What credits get you Each service consumes credits at a different rate: | Service | Credit cost | | -------------- | -------------------- | | Speech to Text | 1 credit per minute | | Text to Speech | 2 credits per minute | | Voice Agents | 6 credits per minute | Which translates to the following per plan: | Plan | Voice Agent minutes | Speech to Text minutes | Text to Speech minutes | | -------------- | ------------------- | ---------------------- | ---------------------- | | **Free** | 9 (one-time) | 50 (one-time) | 25 (one-time) | | **Starter** | 17/month | 100/month | 50/month | | **Creator** | 84/month | 500/month | 250/month | | **Pro** | 834/month | 5,000/month | 2,500/month | | **Business** | 3,334/month | 20,000/month | 10,000/month | | **Enterprise** | Custom | Custom | Custom | Minute equivalents assume a single service consumes your full credit allocation. In practice you can split credits across services in any combination. *** ## Additional Credits Are you on the Creator, Pro, or Business plan and need more credits? You can purchase additional credit packs at any time to supplement your plan allocation. ### Credit Packs | Plan | Top-Up Price | Credits Given | | -------- | ------------ | ------------- | | Creator | \$5 | 100 Credits | | Pro | \$10 | 300 Credits | | Business | \$25 | 1,000 Credits | Additional credits are available for purchase from your [Agents](https://agents.tryhamsa.com/app/billing) or [Media](https://media.tryhamsa.com/app/billing) billing page. Credit packs are one-time purchases, not recurring subscriptions. Free, Starter, and Enterprise plans do not have top-up packs. Add a top-up package. *** ## Usage Limits In addition to credits, some services have per-plan job limits. A job is one API request (for example, one transcription job or one synthesis request). Limits apply on a monthly or daily basis depending on the service. ### Speech to Text (Monthly Limit) | Plan | Monthly Job Limit | | -------------- | ---------------------------------------------- | | **Free** | No separate cap — limited by available credits | | **Starter** | 50 jobs | | **Creator** | 300 jobs | | **Pro** | 2,500 jobs | | **Business** | 8,000 jobs | | **Enterprise** | Custom | ### Text to Speech (Daily Limit) | Plan | Daily Job Limit | | -------------- | ---------------------------------------------- | | **Free** | No separate cap — limited by available credits | | **Starter** | No separate cap — limited by available credits | | **Creator** | 1,500 jobs | | **Pro** | 1,500 jobs | | **Business** | 5,000 jobs | | **Enterprise** | Custom | *** ## Concurrency Limits Voice Agents have a per-plan limit on simultaneous calls: | Plan | Concurrent Calls | | -------------- | ---------------- | | **Free** | 1 call | | **Starter** | 1 call | | **Creator** | 2 calls | | **Pro** | 5 calls | | **Business** | 10 calls | | **Enterprise** | Custom | Speech to Text and Text to Speech have no separate concurrency caps on standard plans. *** ## Knowledge Base Storage Voice agents can be grounded on uploaded knowledge base documents. Storage is limited per plan: | Plan | Knowledge Base Storage | | -------------- | ---------------------- | | **Free** | 1 MB | | **Starter** | 5 MB | | **Creator** | 10 MB | | **Pro** | 50 MB | | **Business** | 100 MB | | **Enterprise** | Custom | *** ## When You Run Out of Credits When your credits are exhausted, API requests return an HTTP `402 Payment Required` error, and the dashboard prompts you to upgrade your plan or — on Creator, Pro, and Business — purchase a credit pack. *** ## Monitoring Your Usage You can monitor your credit usage and limits from Hamsa Agents or Hamsa Media. Go to [Hamsa Agents](https://agents.tryhamsa.com) or [Hamsa Media](https://media.tryhamsa.com) and log in On the left-hand or right-hand side depending on the language you choose, you will find a box containing the current credits in total and the consumed number. Credits Usage component *** ## Upgrading Your Plan If you regularly run out of credits or hit your usage limits, consider upgrading to a higher plan for increased allocations. View detailed plan comparison and pricing Discuss custom Enterprise solutions *** ## FAQs No. The Free plan is a one-time grant of 50 credits when you create your account. It never renews, and you're never charged. To keep using Hamsa after your free credits run out, upgrade to a paid plan. No. Credits on paid plans reset at the start of each billing cycle and do not carry over to the next month. API requests return an HTTP `402 Payment Required` error until your credits renew with the next billing cycle, you upgrade your plan, or you purchase a credit pack. Additional credit packs are available for the Creator, Pro, and Business plans. Free, Starter, and Enterprise plans do not have top-up options. Speech to Text consumes 1 credit per minute of audio, and each plan has a monthly limit on the number of transcription jobs. Text to Speech consumes 2 credits per minute of generated audio, and higher-tier plans have a daily limit on the number of synthesis jobs. *** ## Support Need help understanding your usage or have questions about limits? Get help from our technical team Browse complete documentation # Models Source: https://docs.tryhamsa.com/overview/models Learn about the models that power the Hamsa API > Learn about the models that power the Hamsa API. ## Flagship models ### Text to Speech Async TTS via `/v1/jobs/text-to-speech`
    Natural-sounding output optimized for Arabic dialects
    Multiple Arabic dialects + English
    Async job-based — result delivered via webhook
    Sync TTS via `/v1/realtime/tts`
    Low latency — returns WAV audio directly
    Arabic dialects + English
    Optimized for conversational AI and voice agents
    ### Speech to Text Async STT via `/v1/jobs/transcribe`
    High accuracy transcription for Arabic dialects
    Word-level timestamps
    Speaker diarization support
    Async job-based — result delivered via webhook
    Sync STT via `/v1/realtime/stt`
    Arabic dialects + English
    Base64-encoded audio input
    Returns transcription directly
    End-of-speech detection
    ## Models overview The Hamsa API offers audio processing optimized for Arabic language, with support for multiple dialects and English. | Endpoint | Description | Languages | | ------------------------- | ------------------------------------------- | ------------------------ | | `/v1/jobs/text-to-speech` | Async TTS — job-based with webhook delivery | Arabic dialects, English | | `/v1/realtime/tts` | Sync TTS — returns WAV audio directly | Arabic dialects, English | | `/v1/jobs/transcribe` | Async STT — job-based with webhook delivery | Arabic, English | | `/v1/realtime/stt` | Sync STT — returns transcription directly | Arabic, English | ## Hamsa TTS — Jobs API The Jobs API (`/v1/jobs/text-to-speech`) is an async TTS endpoint. It creates a job and delivers the audio result via webhook. Best for batch processing and media content generation. Use cases: * **Content Creation**: Generate Arabic audio content, podcasts, and videos * **Accessibility**: Audio versions of written Arabic content * **E-Learning**: Educational content in Arabic with natural pronunciation * **Media Production**: Professional-quality voiceovers Parameters: `text`, `voiceId`, `webhookUrl`, `webhookAuth` → See the [TTS Quickstart](/text-to-speech/quickstart) for examples. ## Hamsa TTS — Realtime API The Realtime API (`/v1/realtime/tts`) returns WAV audio directly in the response. Designed for real-time applications and voice agents. Use cases: * **Voice Agents**: Real-time voice agents and phone calls * **Interactive Applications**: Chatbots requiring immediate voice response * **Live Conversations**: Conversational AI applications Parameters: `text`, `speaker`, `dialect`, `mulaw`, `sampleRate`, `expressiveness` ### Supported dialects | Code | Dialect | Example voices | | ------- | ---------------------- | -------------- | | `pls` | Palestinian | Amjad, Layan | | `egy` | Egyptian | Mariam, Samir | | `syr` | Syrian | Dalal, Mais | | `irq` | Iraqi | Lyali, Fatma | | `jor` | Jordanian | Lana, Jasem | | `leb` | Lebanese | Carla, Majd | | `ksa` | Saudi | Hiba, Fahd | | `uae` | Emirati | Salma, Dima | | `bah` | Bahraini | Mazen, Ruba | | `qat` | Qatari | Deema, Faisal | | `kuw` | Kuwaiti | Mai, Hatem | | `oma` | Omani | Aisha, Jaber | | `msa` | Modern Standard Arabic | Salem, Tamim | | `ar-sa` | Arabic – Gulf | Khalid, Rahma | | `en` | English | Emma, James | → See the [TTS Quickstart](/text-to-speech/quickstart) for examples. ## Hamsa STT — Batch API The Batch API (`/v1/jobs/transcribe`) is an async STT endpoint. Submit a media URL and receive the transcription via webhook or polling. Choose from two models: | Model ID | Best for | | --------------------------- | ------------------------------------------------------- | | `Hamsa-General-V2.0` | General-purpose — media, podcasts, pre-recorded content | | `Hamsa-Conversational-V1.0` | Conversational audio — meetings, calls, dialogues | Use cases: * **Transcription Services**: Convert Arabic audio/video content to text * **Meeting Documentation**: Capture and document Arabic conversations with speaker identification * **Media Subtitling**: Generate SRT subtitles for Arabic media content * **Content Analysis**: Process and index Arabic audio content Key features: * Word-level timestamps for each transcribed segment * Speaker diarization for multi-speaker audio * Automatic Arabic dialect detection (set `language` to `ar`) * SRT subtitle export with configurable formatting * Automatic punctuation and formatting Parameters: `mediaUrl`, `model`, `language`, `webhookUrl`, `returnSrtFormat`, `srtOptions` → See the [STT Quickstart](/speech-to-text/quickstart) for examples. ## Hamsa STT — Realtime API The Realtime API (`/v1/realtime/stt`) accepts base64-encoded audio and returns the transcription directly. For streaming, use the [WebSocket API](/websocket/websocket-api). Use cases: * **Voice Agents**: Real-time speech recognition for conversational AI * **Live call transcription**: Transcribe Arabic calls in real time * **Interactive applications**: Immediate transcription for chatbots and voice interfaces Key features: * Synchronous — returns transcription in the response * End-of-speech detection with configurable threshold * Arabic and English language support Parameters: `audioBase64`, `language`, `isEosEnabled`, `eosThreshold` → See the [STT Quickstart](/speech-to-text/quickstart) for examples. ## Model selection guide Use the Jobs API (`/v1/jobs/text-to-speech`) for async processing with webhook delivery. Use the Realtime API (`/v1/realtime/tts`) or WebSocket for low-latency streaming. Both TTS endpoints support 15 Arabic dialects + English. Choose based on latency requirements. Use the Jobs API for professional Arabic content, media, and video narration. Use the Realtime API / WebSocket for real-time conversational applications. Use the Batch API (`/v1/jobs/transcribe`) with `Hamsa-General-V2.0` for media transcription or `Hamsa-Conversational-V1.0` for conversational audio. ## Character limits | Endpoint | Character limit | | ------------- | ---------------------------- | | WebSocket TTS | 2,000 characters per message | For longer content, consider splitting the input into multiple requests. ## Audio duration limits | Endpoint | Audio duration limit | File size limit | | --------------------------------- | -------------------- | --------------- | | Batch API (`/v1/jobs/transcribe`) | 60 minutes | 500 MB | | Realtime API (`/v1/realtime/stt`) | Per-request | N/A | | WebSocket (`/v1/realtime/ws`) | Streaming | N/A | ## Plans and Usage Limits Your subscription plan determines your credit allocation, usage limits, and concurrent call capacity. See [Limits and Usage](/overview/limits-and-usage) for the full per-plan breakdown. ### API requests per minute vs concurrent requests It's important to understand that **API requests per minute** and **concurrent requests** are different metrics that depend on your usage patterns. API requests per minute can be different from concurrent requests since it depends on the length of time for each request and how the requests are batched. **Example 1: Spaced requests** If you had 60 requests per minute that each took 1 second to complete and you sent them each 1 second apart, the max concurrent requests would be 1 and the average would be 1. **Example 2: Batched requests** However, if you had 60 requests per minute that each took 3 seconds to complete but all fired at once, the max concurrent requests would be 60 and the average would be 3. Since our system cares about concurrency, requests per minute matter less than how long each of the requests take and the pattern of when they are sent. # Managing Projects Source: https://docs.tryhamsa.com/overview/projects/managing-projects Create, rename, and manage the lifecycle of your projects ## Creating a Project To create a new project: 1. Click the **project switcher** in the top navigation bar 2. Select **"Create new project"** 3. Enter a name for your project 4. Click **Create** Your new project becomes active immediately and you'll be taken to its workspace. You can start adding agents, knowledge bases, and other resources right away. Use descriptive project names that reflect the purpose or client — for example, "Customer Support - ACME" or "Internal HR Bot". ## Renaming a Project Project owners can rename any project (except the Default project). To rename a project: 1. Open **Project Settings** from the sidebar or project menu 2. Click the **edit icon** next to the project name 3. Enter the new name 4. Save your changes Only the project **Owner** can rename a project. Admins and Users cannot change the project name. ### Personal Display Labels Any team member can set a personal display label for a project — this is a custom name that only they see in the project switcher. It does not change the actual project name for other members. To set a personal label: 1. Open the project switcher 2. Click the **edit icon** next to the project you want to relabel 3. Enter your preferred display name 4. Save ## Deactivating a Project If you want to temporarily disable a project without deleting it, you can deactivate it. **What deactivation does:** * Hides the project from all non-owner members * The owner can still view and manage the project * All data and resources are preserved * The project can be reactivated at any time To deactivate a project: 1. Open **Project Settings** 2. Scroll to the **Danger Zone** section 3. Click **Deactivate Project** 4. Confirm the action Deactivating a project immediately removes it from the view of all collaborators (Admins and Users). They will lose access until you reactivate it. ## Reactivating a Project To reactivate a deactivated project: 1. Open **Project Settings** (you can still access this as the owner) 2. Scroll to the **Danger Zone** section 3. Click **Reactivate Project** The project becomes visible and accessible to all members again immediately. ## Deleting a Project To permanently delete a project, open **Project Settings** and scroll to the **Danger Zone** section. Deletion is permanent and cannot be undone — all resources inside the project will be removed. The **Default project** cannot be deactivated or deleted. ## Related Documentation Learn what projects are and how they work Invite teammates to your project Control what your team members can access # Projects Overview Source: https://docs.tryhamsa.com/overview/projects/overview Organize your work and collaborate with your team using projects ## What is a Project? A project is your workspace on the Hamsa platform. Everything you build — agents, knowledge bases, phone numbers, tools, call history, and more — lives inside a project. When you first sign up, a **Default project** is automatically created for you. You can start building right away, or create additional projects to organize different workstreams, clients, or environments. **Projects allow you to:** * Separate resources by team, client, or use case * Invite teammates and assign them roles * Control what each team member can see and do * Manage your workspace independently from your personal account settings ## The Default Project Every account comes with a Default project. This project: * Is created automatically when your account is set up * Cannot be renamed, deleted, or deactivated * Works exactly like any other project for building and running agents You can create as many additional projects as you need alongside it. ## Switching Between Projects You can switch between projects at any time using the **project switcher** in the top navigation bar. Selecting a different project changes the context for everything in the platform — agents, call history, phone numbers, and all other resources are scoped to the currently selected project. ## Finding Your Project ID Some API endpoints require a **Project ID** to identify which project the request applies to. You can copy your Project ID directly from the project switcher in the top navigation bar — click the switcher and use the copy icon next to the project name. ## What's in a Project? Each project has its own isolated set of resources: | Resource | Description | | ------------------ | ---------------------------------------------------- | | **Agents** | Voice agents built and deployed within this project | | **Knowledge Base** | Documents and content your agents can reference | | **Tools** | Custom integrations and functions for your agents | | **Phone Numbers** | Telephony numbers assigned to agents in this project | | **Call History** | All call recordings, transcripts, and analytics | | **Batch Calls** | Outbound call campaigns | | **Secrets** | API keys and credentials used by your agents | | **Voices** | Custom cloned voices created in this project | | **Members** | Your team collaborators and their access levels | ## Related Documentation Create, rename, and deactivate projects Invite teammates and manage your project members Understand what each role can do and how to customize access Generate API keys for your project # Roles & Permissions Source: https://docs.tryhamsa.com/overview/projects/roles-and-permissions Understand what each role can do and how owners can customize member access ## Overview Every member of a project is assigned a role that determines what they can see and do. There are three roles: | Role | Description | | --------- | -------------------------------------------------------------------- | | **Owner** | Full control over the project, including team management and billing | | **Admin** | Can build and manage content; limited project and team management | | **User** | Can work with agents and content; read-only on sensitive resources | The person who creates a project is automatically its **Owner**. Ownership cannot be transferred. *** ## Default Permissions by Role ### Owner The Owner has full access to everything in the project, including: * Creating, editing, and deleting all resources (agents, tools, knowledge base, phone numbers, voices, etc.) * Managing team members — inviting, changing roles, removing members, and customizing individual permissions * Accessing and managing billing * Deactivating, renaming, and deleting the project * Monitoring live calls and exporting call data ### Admin Admins can do most things, but with a few important limitations: **What Admins can do:** * Create, edit, and delete agents, tools, knowledge base items, voices, and secrets * Make and manage outbound calls and batch call campaigns * View and export call history, monitor live calls * Manage phone numbers (add and edit, but not delete) * Invite new members at the **User** role **What Admins cannot do:** * Rename or delete the project * Deactivate or reactivate the project * Access billing * Change a member's role or manage member permissions * Delete phone numbers * Invite members at the Admin role ### User Users can actively work within the project but have read-only access to sensitive resources and cannot manage the team. **What Users can do:** * Create, edit, and use agents, tools, and knowledge base items * Upload files to the knowledge base * View call history and export call data * View phone numbers (but not add or edit them) * View voices, secrets, and outbound calls (but not create or edit them) **What Users cannot do:** * Delete agents, tools, or knowledge base items * Add, edit, or delete phone numbers * Create or modify voices, secrets, or outbound call campaigns * Invite or manage team members * Access billing * Rename, deactivate, or delete the project *** ## Customizing Member Permissions Beyond the default role permissions, the **Owner** can fine-tune access for any individual member. This allows you to grant extra capabilities to a specific User, or restrict certain actions for an Admin — without changing their role. ### Opening the Permissions Panel 1. Go to **Project Settings → Members** 2. Find the member you want to customize 3. Open their action menu and select **Manage Permissions** A drawer will open showing all available resources and actions, with toggles indicating what the member currently has access to. ### Granting or Revoking Access * Toggle any action **on** to grant that permission * Toggle any action **off** to revoke it * Permissions marked as **Custom** have been changed from the role's default Permission changes may take up to 1 minute to apply. ### Cascade Behavior Some permissions depend on others. If you revoke a member's **read** access to a resource, all other actions for that resource (create, edit, delete, etc.) are automatically revoked as well — since they require read access to function. ### Reverting to Role Defaults If you want to undo your customizations for a member: * Click **Revert to defaults** next to a specific resource to reset just that section * Or use the top-level **Revert all to defaults** option to clear all overrides and return the member fully to their role's standard permissions *** ## Permissions Reference The table below summarizes the key differences between roles across the main areas of the platform. | Area | Owner | Admin | User | | ---------------- | ----------- | ---------------------- | --------------------------------------------- | | Agents | Full access | Full access | Create & edit (no delete) | | Knowledge Base | Full access | Full access | Create & edit (no delete) | | Tools | Full access | Full access | Create & edit (no delete) | | Phone Numbers | Full access | Add & edit (no delete) | View only | | Call History | Full access | Full access | View & export (no delete, no live monitoring) | | Outbound Calls | Full access | Full access | View only | | Voices | Full access | Full access | View only | | Secrets | Full access | Full access | View only | | Members | Full access | Invite Users only | View only | | Billing | Full access | No access | No access | | Project Settings | Full access | View only | View only | | Statistics | Full access | Full access | Full access | *** ## Related Documentation Invite teammates and manage your project members Create, rename, and manage your projects Learn what projects are and how they work # Team Collaboration Source: https://docs.tryhamsa.com/overview/projects/team-collaboration Invite teammates to your project and manage your team members ## Inviting Team Members Project owners and admins can invite teammates to collaborate on a project. To invite someone: 1. Open **Project Settings** from the sidebar 2. Go to the **Members** tab 3. Click **Invite Member** 4. Enter their **email address** 5. Choose a **role** — Admin or User 6. Click **Send Invitation** An invitation email will be sent to the provided address. Once they accept, they'll have access to the project with the assigned role. Admins can invite members at the **User** role only. Only the project Owner can invite someone as an **Admin**. ## The Invitation Flow Here's what happens after you send an invite: 1. **Invitation sent** — The invitee receives an email with a link to join the project 2. **Pending** — The member appears in your members list with a "Pending" status until they accept 3. **Accepted** — Once they click the link and authenticate, their status changes to **Active** and they gain full access based on their role ### Resending an Invitation If an invitation expires before the recipient accepts it, you can resend it: 1. Find the member in the **Members** tab (they'll show a "Pending" status with an expired notice) 2. Open their action menu 3. Click **Resend Invitation** ## Managing Team Members ### Viewing Members All team members are listed in **Project Settings → Members**. The table shows each member's name, email, role, and current status. ### Changing a Member's Role The project owner can change a member's role at any time (between Admin and User). 1. Find the member in the **Members** tab 2. Click the role dropdown next to their name 3. Select the new role Role changes take effect immediately. The member's access will be updated on their next action — changes may take up to 1 minute to fully propagate. ### Removing a Member To remove someone from a project: 1. Find the member in the **Members** tab 2. Open their action menu (the three-dot menu or dropdown) 3. Click **Remove Member** 4. Confirm the action Removing a member immediately revokes their access to the project and all its resources. Only the project **Owner** can remove members. Owners cannot remove themselves from their own project. ## Member Statuses | Status | Description | | ----------- | ------------------------------------------------------ | | **Active** | Member has accepted the invitation and has full access | | **Pending** | Invitation has been sent but not yet accepted | ## Related Documentation Understand what each role can do and how to customize access Create, rename, and manage your projects Learn what projects are and how they work # Quick Start Source: https://docs.tryhamsa.com/overview/quickstart Build your first voice agent in 10 minutes # Build Your First Voice Agent Get started with Hamsa by creating a simple customer support agent. This guide will have you up and running in about 10 minutes. For this quickstart, we'll create a **Single Prompt Agent** - the fastest way to get started. Navigate to **Agents** → **Create New Agent** → **Single Prompt** Give your agent a descriptive name: ``` Agent Name: Customer Support Bot ``` Set the first message callers will hear: ``` Greeting: "Thank you for calling! I'm here to help. How can I assist you today?" ``` Choose **Static** for greeting type. This is your agent's core instructions. Copy and paste this template: ``` ## Identity You are a helpful customer support assistant for Acme Corporation. ## Style Guardrails - Be concise (keep responses under 2 sentences unless explaining complex topics) - Be conversational and friendly - Use natural language and contractions - Be empathetic and patient ## Response Guidelines - Ask only one question at a time - Confirm understanding by paraphrasing - If you don't know something, be honest ## Task Your goal is to help customers with: 1. General product questions 2. Account inquiries 3. Technical support issues If the issue requires human assistance, politely inform the caller that you'll connect them with a specialist. ``` * **Language**: English (US) * **Voice**: Choose any voice - try `aura-asteria-en` for a friendly female voice Preview voices before selecting to find the perfect match for your brand Use these recommended settings for natural conversation: * **Response Delay**: 400ms (default) * **Allow Interruptions**: ON * **User Inactivity Timeout**: 15 seconds * **Max Call Duration**: 300 seconds (5 minutes) Click **Test Agent** in the top right. **Browser Test:** 1. Click "Start Test" in browser 2. Allow microphone access 3. Have a conversation with your agent 4. Check real-time logs in the sidebar **Phone Test (Optional):** 1. Click "Test via Phone" 2. Enter your phone number 3. Receive a call from your agent To make your agent live: 1. Go to **Phone Numbers** tab 2. Purchase or connect a phone number 3. Assign it to your agent 4. Save changes Your agent is now live and ready to take calls! ## What You Built Congratulations! You just created a functional voice agent that can: * Greet callers professionally * Handle general inquiries * Maintain natural conversation flow * Handle interruptions and silence appropriately ## Next Steps Upload company FAQs and documentation Integrate with your APIs and systems Fine-tune voice, timing, and behavior Create complex conversation workflows ## Common Next Steps ### Add a Knowledge Base Give your agent access to company information: 1. Navigate to **Knowledge Bases** → **Create New** 2. Upload documents (PDF, DOC, TXT) or add web URLs 3. Return to your agent settings 4. Select the knowledge base in **Knowledge Base** tab 5. Test with questions about your content ### Add Custom Tools Integrate with your systems: 1. Go to **Tools** → **Create New Tool** 2. Configure your API endpoint 3. Define parameters 4. Add the tool to your agent 5. Update the preamble to mention when to use the tool ### Enable Smart Features Enhance your agent's capabilities: * **Smart Call End**: Automatically end when conversation concludes * **Gender Detection**: Personalize responses based on caller gender * **Agentic RAG**: Advanced knowledge retrieval with reasoning ## Troubleshooting * Check microphone permissions * Verify voice is selected * Ensure preamble is not empty * Try refreshing the page * Try a different voice from the voice library * Adjust response delay (lower = more responsive) * Enable "Thinking Voice" for natural pauses * Increase response delay to 600-800ms * This gives users more time to complete thoughts * Verify phone number format (+1XXXXXXXXXX) * Check your workspace has calling credits * Try browser test first to verify agent works ## Video Tutorial