# 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.
### 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:
**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:
**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:**
* Batch Call starts at selected date & time
* Date & time are required
* Timezone is required
* Batch Call status is SCHEDULED until start time
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 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
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
**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
**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
**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
## 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
### 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
* 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.
## 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.
### Overview
* Session ID, status, start time, and duration
* Channel type
* Performance metrics (ASR, LLM, TTS, Latency) updating in real-time
### 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.
### 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
### 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.
## 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.
## 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.
## 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.
## 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.
## 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:
**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 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:
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:
### 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:
### 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
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
* Click **"Manage"** to open the item selection modal
* Select the items you want to use
* 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:
### 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
### 2. Add a Phone Number
#### For Twilio:
* Click the "Add Number" button
* Select "Twilio" from the dropdown
* 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
#### For SIP Trunk:
* Click the "Add Number" button
* Select "SIP Trunk" from the dropdown
* 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)
* 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
* Click "Test Connection" to verify your 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
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
2. **Open Upload Modal**
* The "Transcribe Files" modal opens
* You'll see a drag-and-drop area
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
2. **Open YouTube Modal**
* The "Transcribe YouTube Video" modal opens
* You'll see URL input field
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
2. **Open Record Modal**
* The "Record Audio" modal opens
* You'll see recording interface
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
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
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
### 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
Sign In - Log in to your account
Continue with Google- Signup - Login using Google Auth
Continue with Microsoft- Signup - Login using Microsoft Auth
# 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.
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
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.
### *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.
***
## 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.
***
## 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
## Need Help?
Ask questions, share experiences, and get help from the Hamsa community
***
**Ready to build something more complex?** Check out our **[Flow Agent Guide](/agents/flow-agent/overview)** to learn about visual conversation design.
# Troubleshooting Guide
Source: https://docs.tryhamsa.com/overview/troubleshooting
Common issues, solutions, and debugging strategies for Hamsa Telephony agents
## Overview
This guide covers common issues you may encounter when building and deploying Hamsa Telephony agents, along with step-by-step solutions and debugging strategies.
**Quick Debug Checklist:**
1. Check the Call History logs for error messages
2. Test your agent in the testing interface
3. Verify all tool configurations
4. Validate variable names and references
5. Check transition conditions
***
## Tool-Related Issues
### Issue: Tool Not Executing
**Symptoms:**
* Tool node is reached but doesn't execute
* No API call is made
* Flow skips to next node immediately
**Common Causes & Solutions:**
#### 1. Tool Not Found in agentSettings.tools
**Diagnosis:**
```bash theme={null}
# Check if tool reference exists
Check: agentSettings.tools array contains entry with nodeId matching your node
```
**Solution:**
* Re-select the tool in the node configuration
* Save the agent to regenerate tool references
* Verify tool is active and not deleted
#### 2. Invalid Tool Configuration
**Diagnosis:**
* Tool has no toolId or persistentId
* Tool type is undefined
* Tool was deleted from tool library
**Solution:**
```yaml theme={null}
# Steps to fix:
1. Go to Tools page
2. Verify tool exists and is active
3. Check tool has valid configuration
4. Re-add tool to node in flow builder
5. Save agent
```
#### 3. Missing Required Parameters
**Diagnosis:**
* Required parameters not provided
* Parameter values are empty or invalid
**Solution:**
```yaml theme={null}
# In node configuration:
Parameters:
- name: required_param
value: { { valid_variable } } # Ensure variable exists
required: true
```
Always verify that variables referenced in parameters exist before the tool node is reached.
***
### Issue: Tool Times Out
**Symptoms:**
* Tool execution exceeds timeout limit
* Call continues but tool results are missing
* Error logged: "Tool execution timeout"
**Solutions:**
#### Increase Timeout
```yaml theme={null}
Tool Node Configuration:
timeout: 30000 # Increase from default (30s) to 60s
onErrorBehavior: continue # Don't fail the call
```
#### Optimize API Performance
* Check target API response time
* Reduce data being requested
* Use caching when possible
* Consider async processing for slow operations
#### Use Processing Message
```yaml theme={null}
Tool Node:
processingMessage: 'This may take a moment, please hold...'
processingMessageType: static
```
***
### Issue: Tool Returns Error
**Symptoms:**
* Tool executes but returns error response
* Error message in logs: "Tool execution failed"
* Flow transitions to error handling
**Debugging Steps:**
#### 1. Test Tool Directly
```yaml theme={null}
# In Flow Builder:
1. Click on tool node
2. Click "Test Tool" button
3. Provide sample parameters
4. Review response and errors
```
#### 2. Check Tool Configuration
* Verify URL is correct and accessible
* Check authentication headers/API keys
* Validate request method (GET, POST, etc.)
* Ensure content-type headers are set
#### 3. Review Parameter Mapping
```yaml theme={null}
# Common issues:
❌ Wrong: url: "api.example.com/users"
✅ Right: url: "https://api.example.com/users"
❌ Wrong: headers: { "Authorization": "{{api_key}}" }
✅ Right: headers: { "Authorization": "Bearer {{api_key}}" }
```
#### 4. Check Response Format
```yaml theme={null}
# If output mapping fails:
Output Mapping:
user_id: $.data.id # Check JSON path is correct
user_name: $.data.name # Use Test Tool to see actual response structure
```
***
### Issue: Tool Override Not Working
**Symptoms:**
* Parameter overrides not applied
* Tool uses default values instead of overrides
* Changes to tool configuration don't take effect
**Solution:**
#### For FUNCTION Tools
```yaml theme={null}
# Full override support:
Tool Reference (in agentSettings.tools):
toolType: 'FUNCTION'
overrides:
url: 'https://custom-api.example.com'
method: 'POST'
parameters:
custom_param: { { my_variable } }
headers:
Authorization: 'Bearer {{api_key}}'
timeout: 15000
```
#### For WEB\_TOOL Tools
```yaml theme={null}
# Limited override support:
Tool Reference (in agentSettings.tools):
toolType: 'WEB_TOOL'
overrides:
name: 'Custom Tool Name' # Only name, description, params
description: 'Modified description'
parameters:
param1: { { custom_value } }
# Cannot override: URL, method, headers, timeout
```
#### For MCP Tools
```yaml theme={null}
# No overrides allowed:
Tool Reference (in agentSettings.tools):
toolType: 'MCP'
# MCP tools are server-managed
# No overrides field available
```
**Tool Type Override Capabilities:**
* **FUNCTION**: Full overrides (URL, method, headers, params, auth, timeout)
* **WEB\_TOOL**: Limited overrides (name, description, params only)
* **MCP**: No overrides (server-managed)
***
### Issue: Tool Version Mismatch
**Symptoms:**
* Warning: "Tool version out of sync"
* Tool behavior changed unexpectedly
* Parameters missing or renamed
**Solution:**
#### Check Version Status
```yaml theme={null}
# In agentSettings.tools:
Tool Reference:
persistentId: 'my-tool'
toolId: 'uuid-v1'
version: 1
# If tool was updated in library:
# version is now 2, causing mismatch
```
#### Sync to Latest Version
```yaml theme={null}
# Steps:
1. Go to Tools page
2. Find the tool
3. Check current version
4. In Flow Builder, click "Sync Tool Version" button
5. Review changes
6. Test agent after syncing
```
Syncing to a new tool version may require updating parameter mappings if the tool's schema changed.
***
## Variable-Related Issues
### Issue: Variable Not Extracted
**Symptoms:**
* Variable is undefined in subsequent nodes
* Condition checking variable always fails
* Output shows empty or null value
**Debugging Steps:**
#### 1. Check Extraction Configuration
```yaml theme={null}
Conversation Node:
extractVariables:
enabled: true # Must be true
variables:
- name: customer_name
description: "Customer's full name"
dataType: string
extractionPrompt: "Extract the customer's full name from the conversation"
isRequired: true
```
#### 2. Verify Extraction Method
```yaml theme={null}
Variable Configuration:
extractionMethod: llm_function_calling # Most reliable
confidenceThreshold: 0.8 # Lower if extraction fails (0.0-1.0)
retryAttempts: 2 # Increase if first attempt fails
```
**Extraction Method Options:**
* `llm_function_calling`: Most accurate, uses LLM function calling (recommended)
* `regex`: Pattern matching, fast but requires exact format
* `nlp`: Natural language processing, good for unstructured data
#### 3. Check Conversation Context
```yaml theme={null}
# Variable extraction requires:
1. User actually provided the information
2. Conversation node had user interaction
3. Extraction prompt is clear and specific
# Example:
Node Prompt: "What is your account number?"
User says: "It's 12345"
Extraction works: ✅
Node Prompt: "Welcome!"
User says: "Hi"
Extraction fails: ❌ (no account number mentioned)
```
***
### Issue: Variable Reference Not Working
**Symptoms:**
* `{{variable_name}}` appears literally in output
* Tool parameter shows `{{variable_name}}` instead of value
* Variable not being substituted
**Solutions:**
#### 1. Check Variable Name
```yaml theme={null}
❌ Wrong: {{customerName}} # camelCase
❌ Wrong: {{customer-name}} # hyphen
✅ Right: {{customer_name}} # snake_case
❌ Wrong: {{ customer_name }} # spaces
✅ Right: {{customer_name}} # no spaces
```
#### 2. Verify Variable Exists
```yaml theme={null}
# Variables must be:
1. Extracted in a previous node
2. Set via output mapping from a tool
3. A system variable
4. Created as custom variable
# Check Variables Panel:
- Open Variables Panel in Flow Builder
- Verify variable appears in list
- Check variable has a value
```
#### 3. Check Variable Scope
```yaml theme={null}
# Variable must be available at point of use:
[Start Node] → extracts customer_name ✅
→ [Node 2] → can use {{customer_name}} ✅
→ [Node 3] → can use {{customer_name}} ✅
# But:
[Node 2] → tries to use {{order_id}} ❌
[Node 3] → extracts order_id ✅
# order_id not available in Node 2!
```
***
### Issue: Enum Variable Validation Fails
**Symptoms:**
* Variable extraction succeeds but validation fails
* Error: "Value not in enum"
* Flow doesn't transition correctly
**Solution:**
```yaml theme={null}
Variable Configuration:
name: priority_level
dataType: string
enumValues:
- 'high' # Must match exactly
- 'medium'
- 'low'
extractionPrompt: "Extract priority as 'high', 'medium', or 'low' (lowercase)"
# Common issue: User says "High" but enum is "high"
# Solution: Include in extraction prompt to specify case
```
***
### Issue: Context Rules Not Applied
**Symptoms:**
* Intelligent context rules not providing recommendations
* Context not being used effectively
* Variable suggestions missing
**Check Context Rules:**
```yaml theme={null}
# 14 Built-in Context Rules:
1. call_duration_seconds → Elapsed time tracking
2. conversation_turn_count → Interaction counting
3. previous_node_id → Navigation history
4. user_sentiment → Emotional state detection
5. conversation_topic → Subject tracking
6. user_intent → Goal detection
7. information_completeness → Data collection progress
8. customer_value_tier → Segmentation
9. urgency_level → Priority detection
10. technical_complexity → Issue classification
11. authentication_status → Security state
12. language_detected → Multilingual support
13. business_hours_status → Time-based routing
14. queue_position → Call center integration
# Context rules are automatic
# Ensure agent prompt references them:
Prompt: "Consider the {{user_sentiment}} and {{urgency_level}} when responding"
```
***
## DTMF Issues
### Issue: DTMF Keys Not Working
**Symptoms:**
* User presses keys but nothing happens
* DTMF transitions don't trigger
* Keys not captured
**Solutions:**
#### 1. Check Phone Provider Support
```yaml theme={null}
# DTMF Requirements:
- Phone carrier must support DTMF tones
- SIP trunk must pass DTMF (RFC 2833 or SIP INFO)
- Test with different phone/provider
```
#### 2. Verify Transition Configuration
```yaml theme={null}
Conversation Node:
transitions:
- type: dtmf
key: '1'
targetNodeId: sales_node
- type: dtmf
key: '2'
targetNodeId: support_node
```
#### 3. Check for DTMF Input Capture Conflict
```yaml theme={null}
❌ Problem:
Conversation Node:
dtmfInputCapture:
enabled: true # Capturing all digits
variableName: account_number
transitions:
- dtmf: key=1 # Won't work! Number keys reserved for capture
✅ Solution: Use non-number keys for navigation
transitions:
- dtmf: key=# # Use # or * for navigation
- dtmf: key=*
```
When DTMF Input Capture is enabled, number keys (0-9) are reserved for capturing the sequence and cannot be used for transitions.
***
### Issue: DTMF Input Not Captured
**Symptoms:**
* Variable remains empty after DTMF input
* Timeout occurs before capture complete
* Wrong digits captured
**Solutions:**
#### 1. Configure Capture Settings
```yaml theme={null}
Conversation Node:
message: 'Please enter your 8-digit account number followed by the pound key'
dtmfInputCapture:
enabled: true
variableName: account_number
digitLimit: 8 # Stop after 8 digits
terminationKey: '#' # Or stop when # is pressed
timeoutMs: 20000 # 20 seconds to enter
```
#### 2. Choose Right Termination Method
```yaml theme={null}
# Option 1: Digit Limit (fixed length)
digitLimit: 8 # For SSN, account numbers
terminationKey: null # Optional
# Option 2: Termination Key (variable length)
digitLimit: null # No fixed limit
terminationKey: "#" # User presses # when done
# Option 3: Both (either condition stops)
digitLimit: 16 # Maximum 16 digits
terminationKey: "#" # Or # to finish early
```
#### 3. Validate Captured Value
```yaml theme={null}
Router Node:
transitions:
- equation: {{account_number}}.length == 8
targetNode: valid_account
- equation: {{account_number}}.length != 8
targetNode: retry_input
```
***
### Issue: DTMF Navigation Not Working (Outbound)
**Symptoms:**
* Agent not navigating outbound IVR menus
* Stuck on IVR prompts
* Can't reach human agent
**Solution:**
```yaml theme={null}
# DTMF Navigation is for OUTBOUND calls only
Global Settings:
dtmfNavigation:
enabled: true
instructions: |
Listen for IVR menu options like "Press 1 for Sales, Press 2 for Support".
Press the appropriate key to navigate.
If you hear "Press 0 for operator", press 0.
digitDelay: 500 # Wait 500ms between keypress
autoOperator: true # Automatically press 0 if menu is complex
maxRetries: 3 # Retry up to 3 times if navigation fails
```
**DTMF Navigation vs DTMF Transitions:**
* **DTMF Navigation**: Agent navigates IVR menus on outbound calls (auto-dials keys)
* **DTMF Transitions**: User presses keys on inbound calls (routing logic)
* **DTMF Input Capture**: Collects digit sequences (account numbers, PINs)
***
## Transition Issues
### Issue: Transition Not Triggering
**Symptoms:**
* Flow gets stuck on a node
* Expected transition doesn't happen
* Falls through to "always" transition unexpectedly
**Debugging Steps:**
#### 1. Check Transition Order
```yaml theme={null}
# Transitions are evaluated TOP TO BOTTOM
Transitions:
- Natural Language: "user wants sales" → Sales_Node # Checked first
- Equation: {{budget}} > 5000 → High_Value_Node # Checked second
- DTMF: key=1 → Option_1 # Checked third
- Always → Default_Node # Last resort
# Always put "Always" transition LAST
```
#### 2. Verify Condition Syntax
```yaml theme={null}
❌ Wrong: {{customer_age}} >= 18
✅ Right: {{customer_age}} >= 18
❌ Wrong: if ({{status}} == "active") { }
✅ Right: {{status}} == "active"
❌ Wrong: {{first_name}} + " " + {{last_name}}
✅ Right: Use tool or custom variable for concatenation
```
#### 3. Test Natural Language Conditions
```yaml theme={null}
# Natural language transitions use LLM to evaluate
# Make conditions specific:
❌ Vague: "user is done"
✅ Specific: "user confirmed they want to complete the purchase"
❌ Vague: "user has question"
✅ Specific: "user asked a question about pricing or features"
```
***
### Issue: Equation Transition Failing
**Symptoms:**
* Equation condition should be true but doesn't trigger
* Variables not being compared correctly
* Unexpected type errors
**Solutions:**
#### 1. Check Data Types
```yaml theme={null}
# Number comparison:
✅ {{age}} >= 18 # age is number
❌ {{age_string}} >= 18 # age_string is "18" (string)
# String comparison:
✅ {{status}} == "active" # Both strings
❌ {{status}} == active # Missing quotes
# Boolean comparison:
✅ {{is_verified}} == true
❌ {{is_verified}} == "true" # String, not boolean
```
#### 2. Handle Null/Undefined
```yaml theme={null}
# Check existence first:
✅ {{customer_name}} != null AND {{customer_name}} != ""
❌ {{customer_name}}.length > 0 # Crashes if null
# Use default values:
✅ ({{score}} ?? 0) > 50 # Default to 0 if undefined
```
#### 3. Test Complex Conditions
```yaml theme={null}
# Break complex conditions into multiple transitions:
❌ Complex:
{{age}} >= 18 AND {{income}} > 50000 AND ({{credit_score}} > 700 OR {{has_cosigner}} == true)
✅ Better: Multiple transitions in order
- Equation: {{age}} >= 18 AND {{income}} > 50000 AND {{credit_score}} > 700 → Approved
- Equation: {{age}} >= 18 AND {{income}} > 50000 AND {{has_cosigner}} == true → Approved_Cosigner
- Always → Denied
```
***
## Call Quality Issues
### Issue: Poor Audio Quality
**Symptoms:**
* Robotic or distorted voice
* Choppy audio
* Echo or feedback
* Voice cuts out
**Solutions:**
#### 1. Adjust Voice Settings
* Try a different voice from the voice library
* Adjust speed settings (default: 1.0)
* Test with different dialects to find the best match
#### 2. Check Network Conditions
* Ensure stable internet connection
* Test with different network
* Check for bandwidth limitations
* Monitor WebRTC connection stats
#### 3. Optimize Transcriber Settings
* Adjust end-of-speech detection threshold if the agent cuts off too early or waits too long
* Check audio input quality and format
***
### Issue: High Latency / Slow Responses
**Symptoms:**
* Long pauses between user speech and agent response
* Delayed reactions
* Conversation feels sluggish
**Solutions:**
#### 1. Optimize Model Settings
```yaml theme={null}
Model Settings:
provider: 'groq' # Fastest
model: 'mixtral-8x7b' # Fast model
maxTokens: 500 # Limit response length
temperature: 0.3 # More deterministic (faster)
```
#### 2. Reduce Tool Call Overhead
```yaml theme={null}
# Minimize tool calls in conversation:
❌ Bad: Tool call for every piece of data
✅ Good: One tool call to fetch all needed data
# Use output mapping to extract multiple variables:
Tool Node:
outputMapping:
name: $.data.name
email: $.data.email
phone: $.data.phone
# Get all data in one call
```
#### 3. Optimize Prompts
```yaml theme={null}
# Shorter prompts = faster response:
❌ Long: 500-word detailed instructions
✅ Short: 100-word focused objective
# Use static messages for fixed content:
messageType: static
message: 'Thank you for calling Acme Corp.'
# No LLM processing needed
```
***
### Issue: Interruption Problems
**Symptoms:**
* User can't interrupt agent
* Agent stops mid-sentence when not appropriate
* Awkward conversation flow
**Solution:**
```yaml theme={null}
# Global interrupt setting (applies to all nodes):
Global Settings:
interrupt: true # Allow interruptions (default)
# For specific nodes that need uninterrupted delivery:
Conversation Node:
skipResponse: false
# User can interrupt by default
# For announcements:
Conversation Node:
skipResponse: true # Auto-advance, no interruption possible
message: "Please hold while I transfer you..."
```
Interruption is controlled at the **global level** in agent settings, not per-node. Use `skipResponse: true` for nodes where you don't want the user to respond at all.
***
## Flow Logic Issues
### Issue: Infinite Loop
**Symptoms:**
* Flow keeps returning to same node
* Call never progresses
* User gets stuck in repeat
**Solutions:**
#### 1. Check for Circular Transitions
```yaml theme={null}
❌ Problem:
Node A → Natural Language: "anything" → Node B
Node B → Natural Language: "anything" → Node A
# Creates infinite loop!
✅ Solution: Add exit condition
Node A → Natural Language: "user wants to exit" → End_Call
Node A → Natural Language: "user needs help" → Node B
Node B → Natural Language: "task complete" → Summary_Node
Node B → Natural Language: "user confused" → Node A (with counter)
```
#### 2. Use Retry Counters
```yaml theme={null}
# Create custom variable to track attempts:
Router Node:
transitions:
- equation: {{retry_count}} >= 3 → Escalate_To_Human
- equation: {{retry_count}} < 3 → Try_Again
# Increment counter in tool or conversation node
```
#### 3. Add Safety Net
```yaml theme={null}
# Every flow should have:
Global Node:
globalCondition: 'user says exit, quit, goodbye, or stop'
targetNode: End_Call_Node
# Ensures user can always exit
```
***
### Issue: Flow Skips Nodes
**Symptoms:**
* Expected node not reached
* Flow jumps over nodes
* Conversation feels incomplete
**Debugging:**
#### 1. Check Call History Logs
```yaml theme={null}
# In Call History:
1. Find the call
2. Open Call Details
3. Go to Logs tab
4. Look for node transitions:
- "Entered node: Node_A"
- "Evaluating transitions..."
- "Transition matched: Node_C" # Skipped Node_B!
```
#### 2. Verify Transition Logic
```yaml theme={null}
# Ensure intended path is possible:
Node A:
transitions:
- Natural Language: "specific condition" → Node B
- Always → Node C # This catches everything else!
# If condition isn't matched, goes to Node C (skipping B)
```
#### 3. Test Systematically
```yaml theme={null}
# Test each transition:
1. Use Test Agent feature
2. Try exact phrases for each transition
3. Verify each path is reachable
4. Check for unreachable nodes (gray in canvas)
```
***
## Global Node Issues
### Issue: Global Node Not Accessible
**Symptoms:**
* User trigger phrase doesn't work
* Global DTMF key doesn't respond
* Global node never reached
**Solutions:**
#### 1. Verify Global Configuration
```yaml theme={null}
Global Node:
isGlobal: true # Must be true
globalConditionType: "prompt" # Or "dtmf"
globalCondition: "user wants to speak to a human operator"
# For DTMF:
globalConditionType: "dtmf"
globalDtmfKey: "0"
```
#### 2. Check Condition Clarity
```yaml theme={null}
❌ Vague: "user has question"
✅ Specific: "user explicitly requests human assistance or operator"
❌ Vague: "user frustrated"
✅ Specific: "user expresses frustration, anger, or dissatisfaction and wants human help"
```
#### 3. Test Global Trigger
```yaml theme={null}
# In Test Agent:
1. Start conversation
2. At any point say exact trigger phrase
3. Should immediately transition to global node
# If doesn't work:
- Rephrase global condition
- Make condition more specific
- Test with different trigger phrases
```
***
## Authentication & API Issues
### Issue: API Key Invalid
**Symptoms:**
* Error: "Invalid API key"
* Authentication failed
* 401 Unauthorized responses
**Solution:**
```yaml theme={null}
# Check API key location:
1. Project Settings → API Keys
2. Verify key is active
3. Check key hasn't expired
4. Regenerate if necessary
# For tool authentication:
Tool Configuration:
headers:
Authorization: "Bearer {{api_key}}" # Correct format
# Ensure api_key variable is set or use direct value
```
***
### Issue: Rate Limiting
**Symptoms:**
* Error: "Too many requests"
* 429 Rate Limit Exceeded
* Some calls fail during high volume
**Solutions:**
#### 1. Implement Retry Logic
```yaml theme={null}
Tool Node:
onErrorBehavior: 'retry'
retryAttempts: 3
errorMessage: 'Having trouble connecting, trying again...'
```
#### 2. Use Caching
```yaml theme={null}
# Cache frequent lookups:
- Customer data: Cache for 5 minutes
- Product catalog: Cache for 1 hour
- System settings: Cache for 24 hours
```
#### 3. Optimize Call Volume
```yaml theme={null}
# Batch operations:
- Fetch multiple records in single API call
- Use webhooks for notifications instead of polling
- Implement queue for non-urgent operations
```
***
## Testing Issues
### Issue: Test Agent Not Working
**Symptoms:**
* Test button doesn't start call
* No audio in test
* Test fails to connect
**Solutions:**
#### 1. Check Browser Permissions
```yaml theme={null}
# Browser must allow:
- Microphone access
- Audio playback
- WebRTC connections
# Chrome: Settings → Privacy → Site Settings → Microphone
# Firefox: Preferences → Privacy & Security → Permissions
```
#### 2. Verify Agent Configuration
```yaml theme={null}
# Agent must have:
- At least one start node
- Valid flow (no isolated nodes)
- All required fields filled
- No validation errors
```
#### 3. Check Network
```yaml theme={null}
# Test requires:
- Stable internet connection
- WebRTC not blocked by firewall
- No VPN interfering with WebRTC
```
***
## Performance Issues
### Issue: High Token Usage
**Symptoms:**
* Expensive calls
* Token usage exceeds expectations
* Billing concerns
**Solutions:**
#### 1. Optimize Prompts
```yaml theme={null}
❌ Bloated:
Prompt: "You are an extremely helpful, very professional, highly trained,
world-class customer service representative with years of experience working
at Fortune 500 companies, specializing in providing exceptional support..."
✅ Concise:
Prompt: "Professional customer service agent. Be helpful and concise."
```
#### 2. Use Appropriate Models
```yaml theme={null}
# Match model to task complexity:
Simple confirmation: GPT-4.1-Mini
Complex reasoning: GPT-4.1
Balance: GPT-4o-mini
```
#### 3. Limit Response Length
```yaml theme={null}
Model Settings:
maxTokens: 200 # Shorter responses
temperature: 0.2 # More focused (fewer tokens)
```
***
## Deployment Issues
### Issue: Agent Not Receiving Calls
**Symptoms:**
* Phone number configured but calls don't reach agent
* Callers get busy signal or error
* Calls go to wrong agent
**Solutions:**
#### 1. Check Phone Number Configuration
```yaml theme={null}
# In Telephony Settings:
1. Verify phone number is purchased and active
2. Check phone number is assigned to this agent
3. Confirm routing rules are correct
4. Test with call forwarding
```
#### 2. Verify Agent Status
```yaml theme={null}
# Agent must be:
- Published (not draft)
- Active (not paused)
- Valid configuration
- No critical errors
```
***
## Getting Help
### Debug Checklist
Before reaching out for support:
* [ ] Check Call History logs for specific call
* [ ] Test agent in Test Agent interface
* [ ] Verify all tool configurations
* [ ] Validate variable names and references
* [ ] Check transition conditions and order
* [ ] Review global settings
* [ ] Test with simple flow to isolate issue
* [ ] Check browser console for JavaScript errors
* [ ] Verify API keys are valid
* [ ] Confirm phone numbers are active
### Support Resources
**Documentation:**
* [Flow Agent Guide](/agents/flow-agent/overview)
* [Variables System](/agents/variables/introduction)
* [Tools Documentation](/overview/features/tools)
* [DTMF Features](/agents/flow-agent/dtmf)
* [Debugging Guide](/agents/flow-agent/debugging)
**Community:**
* GitHub Issues: Report bugs and request features
* Discord: Join community discussions
* Email Support: [support@tryhamsa.com](mailto:support@tryhamsa.com)
**Best Practices:**
* Start simple, add complexity gradually
* Test each change before adding more
* Use descriptive names for nodes and variables
* Document complex logic with node descriptions
* Keep prompts focused and concise
* Monitor call history for patterns
***
## Quick Reference
### Common Error Messages
| Error Message | Likely Cause | Quick Fix |
| ------------------------------ | ----------------------------------- | ------------------------------------------ |
| "Tool not found" | Tool deleted or nodeId mismatch | Re-add tool to node |
| "Variable undefined" | Variable not extracted yet | Check extraction config or node order |
| "Invalid transition condition" | Syntax error in equation | Review equation syntax |
| "DTMF key conflict" | Number keys used with input capture | Use #/\* for navigation or disable capture |
| "Authentication failed" | Invalid API key or expired token | Check API key configuration |
| "Timeout exceeded" | Tool taking too long | Increase timeout or optimize API |
| "Rate limit exceeded" | Too many API calls | Implement retry logic or caching |
| "Node validation failed" | Missing required fields | Review node configuration |
### Status Indicators
| Status | Meaning | Action |
| ---------- | ----------------------------- | ---------------------------- |
| 🟢 Active | Working correctly | None needed |
| 🟡 Warning | Minor issue, still functional | Review and fix when possible |
| 🔴 Error | Critical issue, not working | Fix immediately |
| ⚪ Draft | Not yet published | Test and publish when ready |
| ⏸️ Paused | Temporarily disabled | Re-enable when ready |
***
**Pro Tip:** Enable detailed logging in Global Settings → Advanced → Debug Mode for more verbose error messages and execution traces.
# Improving Accuracy
Source: https://docs.tryhamsa.com/speech-to-text/guides/improving-accuracy
Best practices for high-quality transcription
# Improving Transcription Accuracy
To get the best results from the Speech to Text API, follow these guidelines.
## Audio Quality
* **Format**: Use lossless formats like WAV or flac when possible.
* **Sample Rate**: 16kHz or higher is recommended.
* **Noise**: Minimize background noise and echo.
* **Clarity**: Ensure the speaker is close to the microphone.
## Configuration
* **Language**: Explicitly set the `language` parameter.
## Post-Processing
* **Diarization**: Enable speaker diarization to separate speakers in multi-speaker audio.
# Supported Languages
Source: https://docs.tryhamsa.com/speech-to-text/guides/supported-languages
Languages supported by Speech to Text models
Hamsa STT supports two language codes:
| Code | Language | Notes |
| ---- | -------- | ---------------------------- |
| `ar` | Arabic | All dialects — auto-detected |
| `en` | English | — |
## Arabic dialect detection
When you set `language` to `ar`, the model automatically detects the specific Arabic dialect being spoken. You do not need to specify the dialect. Supported dialects include Egyptian, Gulf, Levantine, Iraqi, and others.
## Code-switching
The models handle speech that naturally switches between Arabic and English, which is common in many Arabic-speaking regions.
## Setting the language
### Batch API
Set the `language` field in your request body. Defaults to `ar` if omitted.
```json theme={null}
{
"mediaUrl": "https://your-storage.com/audio.mp3",
"model": "Hamsa-General-V2.0",
"language": "ar"
}
```
### Realtime API
Set the `language` field in your request body. Defaults to `ar` if omitted.
```json theme={null}
{
"audioBase64": "",
"language": "en"
}
```
### WebSocket
Set the `language` field in the STT payload. Defaults to `ar` if omitted.
```json theme={null}
{
"type": "stt",
"payload": {
"audioBase64": "",
"language": "ar"
}
}
```
# Speech to Text
Source: https://docs.tryhamsa.com/speech-to-text/introduction
Transcribe Arabic and English speech into accurate text with Hamsa STT
Hamsa Speech to Text (STT) transcribes Arabic speech across multiple dialects into text with word-level timestamps and speaker identification. Whether you're transcribing media content, building voice applications, or documenting conversations, Hamsa STT delivers high-accuracy Arabic speech recognition.
## Overview
Technical API documentation for developers
Get started with STT in minutes
## Key features
### Arabic dialect recognition
Hamsa STT is optimized for Arabic speech:
* **Automatic dialect detection**: Set `language` to `ar` and the model detects the dialect automatically
* **Code-switching**: Natural handling of mixed Arabic-English speech
* **Colloquial expressions**: Recognition of dialect-specific idioms and expressions
### Advanced transcription features
* **Word-level timestamps**: Precise timing for each transcribed word — each segment includes word text plus start/end times
* **Word highlight during playback**: In the Media Platform, the current word highlights in sync with playback; click any word to seek
* **Speaker diarization**: Identification of different speakers in multi-speaker audio
* **Automatic punctuation**: Natural punctuation and formatting
* **SRT subtitle export**: Generate formatted subtitles with configurable line/duration options
### Flexible integration
* **Batch API** (`/v1/jobs/transcribe`) — async transcription from media URLs with webhook delivery
* **Realtime API** (`/v1/realtime/stt`) — synchronous transcription from base64-encoded audio
* **WebSocket** (`/v1/realtime/ws`) — streaming transcription for real-time applications
* **Media Platform** — web interface for upload, transcribe, and review
## API endpoints
**Async — `/v1/jobs/transcribe`**
Submit a media URL for transcription. Results delivered via webhook.
Parameters: `mediaUrl`, `model`, `language`, `webhookUrl`
**Sync — `/v1/realtime/stt`**
Send base64-encoded audio, get transcription back directly.
Parameters: `audioBase64`, `language`, `isEosEnabled`, `model`
## 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 |
## Supported languages
The API accepts two language codes:
| Code | Language |
| ---- | ------------------------------------- |
| `ar` | Arabic (all dialects — auto-detected) |
| `en` | English |
Arabic dialect detection is automatic — you do not need to specify the specific dialect. Set `language` to `ar` and the model handles Egyptian, Gulf, Levantine, Iraqi, and other dialects.
## Use cases
### Media transcription
Transcribe Arabic podcasts, videos, and media content:
* Generate subtitles for videos (with SRT export)
* Create searchable transcripts
* Content analysis and indexing
### Voice agents
Power real-time conversational AI:
* Customer service voice agents
* Live call transcription
* Conversation analytics
### Meeting documentation
Document Arabic meetings and interviews:
* Automatic meeting minutes with speaker identification
* Searchable archives
* Compliance and record-keeping
### Content accessibility
Make Arabic audio content accessible:
* Closed captions for videos
* Transcripts for audio content
* Translation preparation
## Getting started
Use the [Batch API](/speech-to-text/quickstart#batch-transcription) for pre-recorded media, the [Realtime API](/speech-to-text/quickstart#realtime-transcription-synchronous) for direct transcription, or the [WebSocket API](/websocket/websocket-api) for streaming.
Use `Hamsa-General-V2.0` for general transcription or `Hamsa-Conversational-V1.0` for conversational audio.
Provide a media URL (batch) or base64-encoded audio (realtime), and get your transcription with timestamps and speaker information.
## Next steps
Build your first STT integration
Real-time streaming transcription
Tips for better transcription accuracy
Use STT via web interface
## FAQ
The Batch API (`/v1/jobs/transcribe`) is async — submit a media URL and receive results via webhook. Use it for pre-recorded files. The Realtime API (`/v1/realtime/stt`) accepts base64-encoded audio and returns the transcription directly. For streaming, use the WebSocket API.
No. Set `language` to `ar` and the model automatically detects the specific dialect (Egyptian, Gulf, Levantine, etc.) and transcribes accordingly.
Yes, the models handle speech that switches between Arabic and English, which is common in many Arabic-speaking regions.
Use `Hamsa-General-V2.0` for general-purpose transcription of media and pre-recorded content. Use `Hamsa-Conversational-V1.0` for conversational audio like calls and meetings.
Yes. Set `returnSrtFormat` to `true` in the Batch API request. You can customize subtitle formatting with `srtOptions`. See the [Quickstart](/speech-to-text/quickstart#srt-options) for details.
# Quickstart
Source: https://docs.tryhamsa.com/speech-to-text/quickstart
Transcribe your first audio file
# Speech to Text Quickstart
Hamsa offers two STT endpoints:
* **Batch API** (`/v1/jobs/transcribe`) — Async job-based. Accepts a media URL and delivers the transcription via webhook or polling.
* **Realtime API** (`/v1/realtime/stt`) — Synchronous. Accepts base64-encoded audio and returns the transcription directly.
## Prerequisites
* [Hamsa API Key](/overview/create-api-keys)
## Batch Transcription
Submit a media URL for transcription. Results are delivered asynchronously.
```bash cURL theme={null}
curl -X POST https://api.tryhamsa.com/v1/jobs/transcribe \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mediaUrl": "https://your-storage.com/audio.mp3",
"model": "Hamsa-General-V2.0",
"language": "ar",
"webhookUrl": "https://your-server.com/webhook"
}'
```
```python Python theme={null}
import requests
url = "https://api.tryhamsa.com/v1/jobs/transcribe"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"mediaUrl": "https://your-storage.com/audio.mp3",
"model": "Hamsa-General-V2.0",
"language": "ar",
"webhookUrl": "https://your-server.com/webhook"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Returns: { "success": true, "data": { "jobId": "..." } }
```
## Realtime Transcription (synchronous)
Send base64-encoded audio and receive the transcription directly.
```bash cURL theme={null}
curl -X POST https://api.tryhamsa.com/v1/realtime/stt \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"audioBase64": "",
"language": "ar",
"model": "s2"
}'
```
```python Python theme={null}
import requests
import base64
# Read and encode your audio file
with open("audio.wav", "rb") as f:
audio_base64 = base64.b64encode(f.read()).decode()
url = "https://api.tryhamsa.com/v1/realtime/stt"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"audioBase64": audio_base64,
"language": "ar",
"model": "s2"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Returns: { "text": "مرحبا بك في خدمة همسة" }
```
## Parameters
### Batch API
| Parameter | Type | Required | Description |
| ----------------- | ------------ | -------- | ----------------------------------------------------------------- |
| `mediaUrl` | string (URI) | Yes | URL of the audio/video file to transcribe |
| `model` | string | Yes | Model to use: `Hamsa-General-V2.0` or `Hamsa-Conversational-V1.0` |
| `language` | string | No | Language code: `ar` (default) or `en` |
| `webhookUrl` | string (URI) | No | URL to receive the completed transcription |
| `webhookAuth` | object | No | Authentication for the webhook |
| `title` | string | No | Optional title for the transcription job |
| `processingType` | string | No | Processing type (default: `async`) |
| `returnSrtFormat` | boolean | No | Return SRT subtitle format (default: `false`) |
| `srtOptions` | object | No | SRT formatting options (see below) |
### SRT Options
When `returnSrtFormat` is `true`, you can customize the subtitle formatting:
| Parameter | Type | Default | Description |
| -------------------------- | ------- | ------- | --------------------------------------- |
| `maxLinesPerSubtitle` | integer | 2 | Maximum lines per subtitle block |
| `singleSpeakerPerSubtitle` | boolean | true | Keep one speaker per subtitle |
| `maxCharsPerLine` | integer | 42 | Maximum characters per line |
| `maxMergeableGap` | number | 0.3 | Max gap (seconds) to merge segments |
| `minDuration` | number | 0.7 | Minimum subtitle duration (seconds) |
| `maxDuration` | number | 7 | Maximum subtitle duration (seconds) |
| `minGap` | number | 0.04 | Minimum gap between subtitles (seconds) |
### Realtime API
| Parameter | Type | Required | Description |
| -------------- | ------- | -------- | ----------------------------------------------------------- |
| `audioBase64` | string | Yes | Base64-encoded audio data (WAV format) |
| `language` | string | No | Language code: `ar` (default) or `en` |
| `isEosEnabled` | boolean | No | Enable end-of-speech detection (default: `false`) |
| `eosThreshold` | number | No | End-of-speech detection threshold, 0.0–1.0 (default: `0.3`) |
| `model` | string | No | The STT model to use: `s2` (default) or `s3` |
## Models
| Model ID | Description |
| --------------------------- | ---------------------------------------------------------------------------------- |
| `Hamsa-General-V2.0` | General-purpose transcription — best for media, podcasts, and pre-recorded content |
| `Hamsa-Conversational-V1.0` | Optimized for conversational audio — best for meetings, calls, and dialogues |
## Streaming via WebSocket
For real-time streaming transcription, use the WebSocket API. See the [WebSocket STT documentation](/websocket/websocket-api) for details.
# Real-time Transcription
Source: https://docs.tryhamsa.com/speech-to-text/real-time
Stream audio for low-latency transcription
Hamsa provides two options for real-time speech-to-text:
* **Realtime API** (`POST /v1/realtime/stt`) — Send base64-encoded audio and receive the transcription directly in the response. Best for short audio clips.
* **WebSocket** (`wss://api.tryhamsa.com/v1/realtime/ws`) — Persistent bidirectional connection for streaming audio. Best for live conversations and continuous transcription.
## Realtime API
The Realtime API accepts base64-encoded audio and returns the transcription synchronously.
See the [Quickstart](/speech-to-text/quickstart#realtime-transcription-synchronous) for usage examples.
### Parameters
| Parameter | Type | Required | Description |
| -------------- | ------- | -------- | ----------------------------------------------------------- |
| `audioBase64` | string | Yes | Base64-encoded audio data (WAV format) |
| `language` | string | No | Language code: `ar` (default) or `en` |
| `isEosEnabled` | boolean | No | Enable end-of-speech detection (default: `false`) |
| `eosThreshold` | number | No | End-of-speech detection threshold, 0.0-1.0 (default: `0.3`) |
| `model` | string | No | The STT model to use: `s2` (default) or `s3` |
## WebSocket Streaming
The WebSocket API provides a persistent connection for streaming audio in real time. Send audio chunks as you record and receive transcription results as they become available.
### Endpoint
```text theme={null}
wss://api.tryhamsa.com/v1/realtime/ws
```
### Authentication
Authenticate via query parameter or header:
```bash theme={null}
wss://api.tryhamsa.com/v1/realtime/ws?api_key=YOUR_API_KEY
```
### Request Format
Send a JSON message with `type: "stt"`:
```json theme={null}
{
"type": "stt",
"payload": {
"audioBase64": "//NExAAAAAANIAcAPABEAEQAQABEAEQARABEA...",
"language": "ar",
"isEosEnabled": true,
"eosThreshold": 0.3,
"model": "s2"
}
}
```
### Response
The server sends the transcribed text directly as a plain string (not JSON).
For full WebSocket documentation including connection handling, error codes, and code examples, see the [WebSocket API reference](/websocket/websocket-api#speech-to-text-stt).
# Text to Speech
Source: https://docs.tryhamsa.com/text-to-speech/introduction
Convert text into natural-sounding Arabic and English speech with Hamsa TTS
Hamsa Text to Speech (TTS) converts written text into natural-sounding audio with proper Arabic pronunciation, intonation, and support for multiple dialects. Whether you're creating media content, building voice applications, or making content accessible, Hamsa TTS delivers high-quality Arabic speech synthesis.
## Overview
Technical API documentation for developers
Get started with TTS in minutes
## Key features
### Arabic dialect support
Hamsa TTS supports a wide range of Arabic dialects:
* **Multiple dialects**: Egyptian, Gulf, Levantine, Iraqi, and Modern Standard Arabic
* **Natural pronunciation**: Proper handling of Arabic phonetics and pronunciation rules
* **Code-switching**: Handling of mixed Arabic-English text
* **Diacritical marks**: Support for tashkeel and proper pronunciation
### High-quality voices
* Pre-built Arabic voices optimized for different dialects
* Custom [voice cloning](/text-to-speech/voice-cloning) for brand consistency
* Gender and age variety
### Flexible integration
* **REST API** for programmatic access — both [async jobs](/api-reference/endpoint/generate-tts) and [realtime](/api-reference/endpoint/rt-generate-tts)
* **WebSocket** for [streaming TTS](/websocket/websocket-tts)
* **Media Platform** [web interface](/media/text-to-speech/overview)
## API endpoints
Hamsa provides two TTS endpoints for different use cases:
**Async — `/v1/jobs/text-to-speech`**
Initiates a TTS job and delivers the result via webhook. Best for batch processing and media content generation.
Parameters: `text`, `voiceId`, `webhookUrl`
**Sync — `/v1/realtime/tts`**
Returns WAV audio directly in the response. Best for real-time voice agents and interactive 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 |
## Getting started
Use the [Realtime API](/text-to-speech/quickstart#realtime-tts-synchronous) for direct audio, the [Jobs API](/text-to-speech/quickstart#jobs-api-async) for async processing, or the [Media Platform](/media/text-to-speech/overview) web interface.
Choose a voice and dialect that matches your target audience from the table above.
Call the API with your text and voice selection. See the [Quickstart](/text-to-speech/quickstart) for examples.
## Next steps
Build your first TTS integration
Explore available voices
Learn about custom voice cloning
Use TTS via web interface
## FAQ
The Jobs API (`/v1/jobs/text-to-speech`) is async — it creates a job and delivers the audio via webhook. Use it for batch processing. The Realtime API (`/v1/realtime/tts`) returns WAV audio directly in the response — use it for real-time applications and voice agents.
Yes, Hamsa TTS handles code-switching between Arabic and English.
Choose the dialect that matches your target audience. Egyptian Arabic has wide recognition across the Arab world. Gulf dialects are preferred in GCC countries. Levantine is common in the Levant region. For formal content, use Modern Standard Arabic (MSA).
Yes, Hamsa supports custom voice cloning. See the [voice cloning guide](/text-to-speech/voice-cloning) for details.
The Realtime API returns 16-bit PCM (WAV) audio at 16 kHz by default. For telephony use cases you can either request 8 kHz PCM via the `sampleRate` parameter (`"8k"`), or enable μ-law encoding via the `mulaw` parameter (μ-law is always 8 kHz — don't combine it with `sampleRate`).
# Quickstart
Source: https://docs.tryhamsa.com/text-to-speech/quickstart
Convert text into lifelike speech
# Text to Speech Quickstart
Hamsa offers two TTS endpoints:
* **Jobs API** (`/v1/jobs/text-to-speech`) — Async job-based. Returns a job ID; audio is delivered via webhook or polling.
* **Realtime API** (`/v1/realtime/tts`) — Synchronous. Returns a WAV audio file directly.
## Prerequisites
* [Hamsa API Key](/overview/create-api-keys)
## Realtime TTS (synchronous)
Returns audio directly in the response.
```bash cURL theme={null}
curl -X POST https://api.tryhamsa.com/v1/realtime/tts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "أهلاً و سهلاً بكم في همسة!",
"speaker": "Amjad",
"dialect": "pls",
"expressiveness": 1
}' \
--output speech.wav
```
```python Python theme={null}
import requests
url = "https://api.tryhamsa.com/v1/realtime/tts"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"text": "أهلاً و سهلاً بكم في همسة!",
"speaker": "Amjad",
"dialect": "pls",
"expressiveness": 1
}
response = requests.post(url, headers=headers, json=data)
with open("speech.wav", "wb") as f:
f.write(response.content)
```
## Jobs API (async)
Initiates a TTS job. The result is delivered via webhook or can be polled.
```bash cURL theme={null}
curl -X POST https://api.tryhamsa.com/v1/jobs/text-to-speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "أهلاً و سهلاً بكم في همسة!",
"voiceId": "Amjad",
"webhookUrl": "https://your-server.com/webhook"
}'
```
```python Python theme={null}
import requests
url = "https://api.tryhamsa.com/v1/jobs/text-to-speech"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"text": "أهلاً و سهلاً بكم في همسة!",
"voiceId": "Amjad",
"webhookUrl": "https://your-server.com/webhook"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Returns: { "success": true, "data": { "id": "...", "status": "PENDING", ... } }
```
## Parameters
### Realtime API
| Parameter | Type | Required | Description |
| ---------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `text` | string | Yes | The text to convert to speech |
| `speaker` | string | Yes | Voice name (e.g., "Amjad", "Layan") or UUID of a cloned voice |
| `dialect` | string | No | Dialect code (e.g., `pls`, `egy`, `ksa`) — see [supported dialects](#supported-dialects) |
| `mulaw` | boolean | No | Use μ-law encoding for telephony (default: `false`) |
| `sampleRate` | string | No | Output sample rate of the PCM audio: `8k` or `16k` (default: `16k`). PCM only — cannot be combined with `mulaw` (μ-law output is always 8 kHz) |
| `expressiveness` | number | No | How expressive the speech sounds, 0 (flat) to 2 (highly expressive) (default: `1`) |
### Jobs API
| Parameter | Type | Required | Description |
| ------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `text` | string | Yes | The text to convert to speech |
| `voiceId` | string | Yes | Voice ID to use. For cloned voices, [preload first](/api-reference/endpoint/preload-cloned-tts-voice) |
| `webhookUrl` | string | No | URL to receive the completed job result |
| `webhookAuth` | object | No | Authentication for the webhook |
## 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 |
# Voice Cloning
Source: https://docs.tryhamsa.com/text-to-speech/voice-cloning
Create custom AI voices from your own audio samples
## Overview
Voice Cloning allows you to create custom AI voices that match specific tones, accents, or brand identities. Upload audio samples or record your voice, and our system generates a unique AI voice you can use in your agents.
**Voice Cloning Features:**
* Create unlimited custom voices
* Upload audio files or record directly
* Support for multiple languages and dialects
* Preview voices before finalizing
* Full integration with agent voice selection
## How Voice Cloning Works
1. **Provide Audio Sample** - Upload or record voice audio
2. **Configure Voice Details** - Name, tags, language, dialect
3. **Processing** - System analyzes and creates AI voice model
4. **Preview & Test** - Generate TTS preview to hear result
5. **Use in Agents** - Select custom voice like any library voice
Voice cloning quality depends on audio sample quality. Clear, noise-free recordings produce the best results.
## Creating a Custom Voice
### Step 1: Voice Details
#### Basic Information
**Name** (Required)
* Descriptive name for your voice
* Example: "Customer Service - Sarah", "Sales - Professional Male"
* Max 100 characters
* Helps identify voice in library
**Description** (Optional)
* Additional context about the voice
* Use case or characteristics
* Not visible to end users
**Language** (Required)
Choose the primary language:
* **English** - For English-speaking markets
* **Arabic** - For Arabic-speaking markets
Select the language that matches how the voice will be used. This affects pronunciation and natural speech patterns.
#### Dialect Selection
**For Arabic Voices:**
Choose specific regional dialect:
* Egyptian (EG)
* Jordanian (JO)
* Saudi Arabian (SA)
* UAE (AE)
* Gulf
* Levantine
* North African
**For English Voices:**
Dialect not required - English voices adapt to general pronunciation.
Selecting the correct dialect ensures natural pronunciation of regional expressions and accents.
#### Voice Tags (Required)
Select exactly **2 tags** - one from each category:
**Gender:**
* **Male** - Masculine voice
* **Female** - Feminine voice
**Style:**
* **Conversational** - Natural, friendly tone for dialogues
* **Narrator** - Clear, articulate tone for announcements
**Why tags matter:**
* Help organize your custom voices
* Enable filtering in voice library
* Communicate voice characteristics to team
* Match voices to use cases
#### Cover Image (Optional)
Upload a visual representation:
* **Formats**: JPG, JPEG, PNG
* **Max Size**: 5 MB
* **Recommended**: Professional headshot or brand logo
* **Usage**: Displays in voice cards
Use consistent cover images across custom voices for easy brand recognition.
### Step 2: Input Audio
Choose how to provide your voice sample:
#### Option A: Upload Audio File
**Supported Formats:**
* MP3
* WAV
* WebM
* OGG
* AAC
* M4A
* FLAC
**Requirements:**
* **Max File Size**: 35 MB
* **Quality**: Clear, noise-free audio
* **Content**: Natural speech, varied sentences
**Upload Process:**
1. Click **Upload** tab
2. Drag and drop audio file or click to browse
3. Wait for upload (progress bar shown)
4. File validated automatically
**Best Practices for Uploaded Audio:**
* Use high-quality recording equipment
* Record in quiet environment
* Avoid background noise and echo
* Include varied speech patterns
* Speak naturally at normal pace
* Include different sentence types (questions, statements)
#### Option B: Record Voice
Record directly in the browser:
**Requirements:**
* **Duration**: 3-20 seconds
* **Format**: WAV (automatic)
* **Microphone**: Required
**Recording Process:**
1. Click **Record** tab
2. Grant microphone permission
3. Click **Start Recording**
4. Speak naturally for 3-20 seconds
5. Click **Stop Recording**
6. Review recording
7. Re-record if needed
**Recording Tips:**
* Use good quality microphone
* Minimize background noise
* Speak at natural pace
* Include varied inflection
* Say 2-3 complete sentences
* Don't rush or speak too slowly
**Recording Length:**
* Minimum: 3 seconds (validation error if shorter)
* Maximum: 20 seconds (recording stops automatically)
### Step 3: Generate TTS Preview
Before finalizing, preview how your custom voice sounds:
**Preview Process:**
1. Enter sample text (minimum 5 words)
2. Click **Generate Preview**
3. System processes voice sample
4. Audio preview generates (10-30 seconds)
5. Click play to listen
6. Regenerate with different text if needed
**Preview Text Suggestions:**
```
"Hello, thank you for calling. How can I help you today?"
"Welcome to Acme Corporation. I'm here to assist with any questions you may have."
"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.
**Preview Validation:**
* Text must contain at least 5 words
* Word count displayed in real-time
* "✓ Valid" indicator when requirements met
**Preview Status:**
* **Generating Preview\...** - Processing voice sample
* **Preview Ready** - Audio ready to play
* **Preview Failed** - Error occurred, try again
### Step 4: Create Voice
Once satisfied with the preview:
1. Click **Create** button
2. Voice processes (usually 30-60 seconds)
3. Success message appears
4. Voice added to "My Voices" library
5. Available immediately in agent voice selection
Voice created successfully! You can now use it in your agents.
## Audio Quality Requirements
### Recording Environment
**Ideal:**
* Quiet room with minimal echo
* Sound-dampening materials (curtains, furniture)
* Closed windows and doors
* No HVAC or fan noise
**Avoid:**
* Outdoor recordings
* Rooms with hard surfaces (echo)
* Areas with background conversations
* Near computers or electronics (buzz/hum)
### Microphone Selection
**Good Options:**
* USB condenser microphone
* Headset with noise cancellation
* Dedicated podcasting microphone
* Laptop built-in mic (in quiet environment)
**Poor Options:**
* Phone speakerphone
* Far-field microphones
* Low-quality earbuds
* Heavily compressed audio sources
### Audio Sample Content
**Include variety:**
* Questions ("How can I help you today?")
* Statements ("Your order has shipped")
* Different emotions (friendly, professional, reassuring)
* Various sentence lengths
* Natural pauses and inflection
**Avoid:**
* Monotone speech
* Reading lists or numbers only
* Repetitive phrases
* Shouting or whispering
* Background music or effects
## 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, etc.)
### Using Custom Voices
Custom voices work identically to library voices:
**In Single Prompt Agents:**
1. Open agent settings
2. Navigate to Voice Settings
3. Click Select Voice
4. Go to "My Voices" tab
5. Select your custom voice
**In Flow Agents:**
* Available in global voice settings
* Can be used in node-level voice overrides
* Appears in all voice selectors
### Deleting Custom Voices
Deleting a custom voice is permanent and cannot be undone.
**Before deleting:**
* Remove voice from all agents using it
* Export/save audio sample if you want to recreate later
* Consider deactivating instead of deleting
**Delete Process:**
1. Find voice in "My Voices" tab
2. Click voice actions menu (⋮)
3. Select **Delete Voice**
4. Confirm deletion
5. Voice removed from library
**What happens to agents:**
* Agents using deleted voice will show error
* Must select new voice for affected agents
* Previous calls with that voice remain in history
## Voice Cloning Best Practices
### Sample Selection
**For customer service voices:**
* Friendly, helpful tone
* Clear enunciation
* Moderate pace
* Warm inflection
**For sales voices:**
* Confident, enthusiastic
* Engaging energy
* Natural variation
* Professional but personable
**For technical support:**
* Clear, methodical pace
* Patient tone
* Reassuring demeanor
* Precise pronunciation
### Multi-Voice Strategy
Create voice variations for different scenarios:
**Example: Customer Service Department**
```
Voice 1: "Customer Service - Friendly Female"
- Tag: Female, Conversational
- Use: General inquiries, warm greeting
Voice 2: "Customer Service - Professional Male"
- Tag: Male, Narrator
- Use: Account information, formal communications
Voice 3: "Customer Service - Calm Female"
- Tag: Female, Conversational
- Use: Complaint handling, de-escalation
```
### Language and Dialect Matching
**For Arabic markets:**
* Egyptian: Broad Middle East appeal
* Gulf (Saudi, UAE): GCC business markets
* Levantine: Jordan, Syria, Lebanon regions
* Use dialect matching target customer base
**For English markets:**
* Clear, neutral accent for international
* Regional accents for local businesses
* Professional pronunciation for all markets
### Testing Custom Voices
**Before deploying:**
1. **Preview Testing** - Generate multiple TTS previews with different scripts
2. **Agent Testing** - Use in test agent with actual conversation flow
3. **Team Review** - Have colleagues listen and provide feedback
4. **A/B Testing** - Compare with library voices
5. **Live Testing** - Deploy to small percentage of calls first
**Quality Checklist:**
* [ ] Pronunciation is clear and natural
* [ ] Pace is appropriate for use case
* [ ] Tone matches brand personality
* [ ] No robotic or artificial sound
* [ ] Handles varied sentence types well
* [ ] Emotional range is appropriate
* [ ] Consistent quality across different texts
## Common Issues
### "Recording too short" error
**Problem:** Recording is less than 3 seconds
**Solution:**
* Record longer sample (5-7 seconds recommended)
* Speak 2-3 complete sentences
* Don't rush through the recording
### "Audio file too large" error
**Problem:** File exceeds 32 MB
**Solution:**
* Compress audio file
* Use MP3 format with lower bitrate
* Trim unnecessary silence
* Use online audio compression tool
### "Preview generation failed"
**Problem:** TTS preview won't generate
**Possible causes:**
* Audio quality too low
* Audio sample too short/long
* Server processing issue
**Solutions:**
* Try uploading different audio sample
* Ensure clean, clear recording
* Check file format is supported
* Try again (temporary issue)
### Voice sounds robotic or unnatural
**Problem:** Generated voice doesn't sound natural
**Causes:**
* Low-quality audio sample
* Background noise in recording
* Insufficient audio variation
* Overly monotone source
**Solutions:**
* Re-record in quieter environment
* Use better microphone
* Include more natural speech variation
* Speak with natural inflection
### Can't find custom voice in agent
**Problem:** Created voice doesn't appear in voice selector
**Solutions:**
* Check "My Voices" tab specifically
* Refresh browser page
* Verify voice creation completed successfully
* Check project selection is correct
## Voice Cloning Limits
**Per Account:**
* Unlimited custom voices
* 32 MB max file size per upload
* 3-9 seconds for direct recording
**Processing Time:**
* Voice creation: 30-60 seconds
* TTS preview generation: 10-30 seconds
**Storage:**
* Custom voices stored permanently
* Cover images: 5 MB max each
## Advanced Features
### Instant Voice (Beta)
Premium feature for voice isolation and enhancement:
**Features:**
* Removes background noise from samples
* Enhances voice clarity
* Improves consistency
* Better quality with less-than-perfect recordings
Instant Voice is a premium beta feature. Contact sales for access.
### Voice Versioning
Create multiple versions of same voice:
**Use case:** Update voice without losing original
1. Create new voice with same base audio
2. Use different tags or names to distinguish
3. Test new version before switching agents
4. Keep old version as backup
## Related Documentation
Browse and select from pre-built AI voices
Configure voice in Single Prompt Agents
Set up voices in Flow Agents
Test your custom voice in real calls
# Voices
Source: https://docs.tryhamsa.com/text-to-speech/voices
Browse and select AI voices for your agents from our extensive voice library
## Overview
Choose from a diverse library of AI voices to give your agent the perfect personality and tone. Browse voices by gender, language, style, and dialect, then preview and select the one that best represents your brand.
**Voice Library Features:**
* Multiple languages (English, Arabic)
* Regional dialects
* Conversational and narrator styles
* Favorite management
* Recently used tracking
* Audio previews for every voice
## Voice Library
### Browsing Voices
Navigate to **Voices** in the sidebar to access the voice library.
**Four tabs organize voices:**
1. **All Voices** - Complete library of available voices
2. **Favorite Voices** - Voices you've marked as favorites
3. **Currently Used** - Voices recently used in your agents
4. **My Voices** - Custom voices you've created
### Voice Cards
Each voice displays:
* **Name** - Voice identifier
* **Profile Image** - Visual representation
* **Language** - English or Arabic
* **Location/Dialect** - Country or regional accent
* **Gender** - Male or Female
* **Style** - Conversational or Narrator
* **Play Button** - Preview the voice
* **Favorite Icon** - Add/remove from favorites
### Playing Voice Previews
**To preview a voice:**
1. Find a voice card
2. Click the **Play** button
3. Listen to the audio sample
4. Click again to stop playback
Preview multiple voices to compare tones, paces, and styles before selecting one for your agent.
## Filtering Voices
Use filters to narrow down the voice library:
### Gender Filter
* **Male** - Masculine voices
* **Female** - Feminine voices
* **Both** - Show all genders
### Language Filter
* **English** - English language voices
* **Arabic** - Arabic language voices
* **Both** - Show all languages
### Style Filter
* **Conversational** - Natural, friendly voices for conversation
* **Narrator** - Clear, articulate voices for announcements
* **Both** - Show all styles
### Dialect Filter
Select specific regional accents (Arabic only):
**Arabic Dialects:**
* Palestinian (pls)
* Egyptian (egy)
* Syrian (syr)
* Iraqi (irq)
* Jordanian (jor)
* Lebanese (leb)
* Saudi (ksa)
* Emirati (uae)
* Bahraini (bah)
* Qatari (qat)
* Kuwaiti (kuw)
* Omani (oma)
* Modern Standard Arabic (msa)
* Arabic – Gulf (ar-sa)
Dialect filtering is only available for Arabic voices. English voices don't have dialect options.
### Search
**Search by voice name:**
```
Type in search box: "Sarah", "Ali", "Professional"
```
The search filters voices in real-time as you type.
### Clear Filters
Click **Clear Filters** to reset all filters and show the complete library.
### Filter Results Count
The interface shows: "Filter Result X Voice" to indicate how many voices match your current filters.
## Managing Favorites
### Add to Favorites
1. Find a voice you like
2. Click the **Star icon** on the voice card
3. Voice is added to "Favorite Voices" tab
Voice added to favorites successfully!
### Remove from Favorites
1. Go to **Favorite Voices** tab (or find the voice anywhere)
2. Click the **filled Star icon**
3. Voice is removed from favorites
### Using Favorites
**Benefits of favoriting voices:**
* Quick access to preferred voices
* Easily compare your top choices
* No need to search repeatedly
* Share favorite voice IDs with team members
Build a curated collection of 3-5 favorite voices for different use cases: customer service, sales, support, etc.
## Using Voices in Agents
### In Single Prompt Agents
1. Open your Single Prompt Agent
2. Navigate to **Voice Settings**
3. Click **Select Voice**
4. Browse, filter, and preview voices
5. Click voice card to select
6. Voice is applied to your agent
**Voice settings also include:**
* Voice speed adjustment
* Language selection
* Temperature control
### In Flow Agents
Flow agents can use different voices for different scenarios:
**Global Voice** (All nodes):
1. Open Flow Agent settings
2. Navigate to **Voice Settings**
3. Select default voice for the entire flow
**Node-Level Override:**
1. Select a Conversation Node
2. In node settings, override the voice
3. This node will use a different voice
**Example Use Case:**
```
Main Voice: Professional female English voice
Transfer Node Voice: Calm male voice saying "Please hold while I transfer you"
Emergency Node Voice: Clear, authoritative voice for urgent messages
```
## Voice Details
Each voice in the library includes:
### Basic Information
**Name** - Unique voice identifier
* Example: "Sarah - Professional", "Ali - Friendly"
**Gender** - Male or Female
* Helps match brand personality
* Affects how customers perceive the agent
**Language** - English or Arabic
* Must match agent's conversation language
* Determines available dialects
### Regional Information
**Location/Dialect**
* English: US, UK, Australia, Canada, India
* Arabic: Egypt, Jordan, Saudi Arabia, UAE, etc.
**Dialect Code**
* Short dialect code (e.g., `egy`, `jor`, `ksa`, `uae`)
* Used in API integrations
### Style Information
**Voice Style/Type**
**Conversational**
* Natural, friendly tone
* Best for: Customer service, sales, support
* Sounds like a helpful person
**Narrator**
* Clear, articulate delivery
* Best for: Announcements, instructions, information
* Sounds like a professional speaker
### Audio Preview
Every voice includes an audio sample showing:
* Pronunciation and clarity
* Speaking pace
* Tone and personality
* Accent and dialect
## Recently Used Voices
The **Currently Used** tab shows voices you've recently used in agents.
**Features:**
* Automatically updated when you select a voice
* Shows most recent at the top
* Includes voices across all agents in project
* Quick access for consistency
**Use cases:**
* Maintain brand consistency across agents
* Quickly find the voice you used last week
* Remember which voice worked well
## Copy Voice Information
**Copy Voice ID:**
1. Open voice card actions menu
2. Click **Copy ID**
3. Voice ID copied to clipboard
**Copy Voice Name:**
1. Open voice card actions menu
2. Click **Copy Name**
3. Voice name copied to clipboard
Voice IDs are useful for API integrations and programmatic agent configuration.
## Voice Selection Best Practices
### Matching Voice to Use Case
**Customer Service**
* Style: Conversational
* Tone: Friendly, helpful, patient
* Gender: Match your brand preference
**Sales**
* Style: Conversational
* Tone: Confident, enthusiastic, engaging
* Gender: Test both to see what converts better
**Support (Technical)**
* Style: Narrator or Conversational
* Tone: Clear, professional, reassuring
* Gender: Clear pronunciation matters most
**Announcements**
* Style: Narrator
* Tone: Authoritative, clear
* Gender: Match company voice
**Appointment Reminders**
* Style: Conversational
* Tone: Friendly but professional
* Gender: Neutral preference
### Brand Alignment
**Formal Brands** (Law firms, financial services)
* Professional, clear voices
* Narrator style or formal conversational
* Slower pace
**Casual Brands** (Retail, hospitality)
* Friendly, warm voices
* Conversational style
* Natural pace
**Tech Brands** (Software, startups)
* Modern, clear voices
* Conversational style
* Efficient pace
### Language and Dialect Considerations
**English Markets:**
* US voices for North American audience
* UK voices for European audience
* Consider local accents for regional businesses
**Arabic Markets:**
* Match dialect to target region
* Egyptian Arabic for broad Middle East appeal
* Gulf dialects (Saudi, UAE) for GCC markets
* Levantine (Jordan, Syria) for Levant region
### Testing Voices
**Before committing to a voice:**
1. **Preview extensively** - Listen to full sample multiple times
2. **Test with content** - Use in test calls with your actual script
3. **Get feedback** - Have team members and test users listen
4. **Compare options** - Test 2-3 similar voices side by side
5. **Check consistency** - Ensure voice works across all scenarios
Don't select a voice based solely on the preview. Test it in actual conversation scenarios to ensure it works well for your specific use case.
## Common Voice Issues
### Voice Sounds Too Fast
**Solution:** Adjust voice speed in agent settings
* Go to Voice Settings
* Reduce speed percentage
* Test again
### Voice Doesn't Match Brand
**Solution:** Refine filters and test more options
* Revisit gender, style, dialect choices
* Preview more voices in your preferred category
* Consider custom voice cloning
### Can't Find Previously Used Voice
**Solution:** Check Recently Used tab
* Go to "Currently Used" tab
* Sort by most recent
* Or use search with voice name
### Favorite Icon Not Working
**Solution:** Ensure project is selected
* Check project dropdown
* Reload page if needed
* Try toggling favorite again
## Limits and Quotas
**Voice Library:**
* No limit on how many voices you can preview
* No limit on favorites
* Recently used shows last 20 voices
**Voice Usage:**
* Each agent can use one voice (or multiple via node overrides in Flow Agents)
* Voice selection is instant
* No processing time required
## Voice Library Updates
The Hamsa voice library is regularly updated with new voices:
* New languages and dialects
* Improved voice quality
* Additional styles and tones
Check back periodically to discover new voices that might better fit your needs.
## Related Documentation
Create custom voices with your own audio
Configure voice settings in Single Prompt Agents
Set up voices in Flow Agents
Test how your voice sounds in real calls
# Real-Time WebSocket API
Source: https://docs.tryhamsa.com/websocket/websocket-api
Connect to Hamsa's real-time WebSocket API for streaming Text-to-Speech and Speech-to-Text
## Overview
The Hamsa Real-Time WebSocket API enables bidirectional streaming communication for Text-to-Speech (TTS) and Speech-to-Text (STT) operations. A single persistent connection can handle multiple requests without reconnecting.
## Connection
### Endpoint
```text theme={null}
wss://api.tryhamsa.com/v1/realtime/ws
```
### Authentication
Authenticate using your API key via query parameter or header:
```bash Query Parameter theme={null}
wss://api.tryhamsa.com/v1/realtime/ws?api_key=YOUR_API_KEY
```
```bash Header theme={null}
X-Api-Key: YOUR_API_KEY
```
### Connection Response
Upon successful connection, the server sends:
```json theme={null}
{
"type": "info",
"payload": {
"message": "Connected to realtime WebSocket server"
}
}
```
Connections are automatically closed after 60 minutes of inactivity. The server sends ping frames every 30 seconds to keep connections alive.
## Message Format
All messages follow this structure:
```typescript theme={null}
interface WebSocketMessage {
type: "tts" | "stt" | "response" | "error" | "info" | "ack" | "end";
payload?: object;
}
```
| Type | Direction | Description |
| ---------- | --------------- | ---------------------- |
| `tts` | Client → Server | Text-to-Speech request |
| `stt` | Client → Server | Speech-to-Text request |
| `ack` | Server → Client | Request acknowledgment |
| `response` | Server → Client | Response data |
| `end` | Server → Client | Stream completion |
| `error` | Server → Client | Error message |
| `info` | Server → Client | Informational message |
***
## Text-to-Speech (TTS)
Convert text to speech with streaming audio output.
### Request
Must be `"tts"`
The text to synthesize. Maximum 2000 characters.
Voice name (e.g. `Amjad`) or the UUID of a custom cloned voice. Pick a speaker that matches the chosen dialect.
Dialect to synthesize. One of: `pls`, `egy`, `syr`, `irq`, `jor`, `leb`, `ksa`, `uae`, `bah`, `qat`, `kuw`, `oma`, `msa`, `ar-sa`, `en`. See [Dialects and Voice Examples](#dialects-and-voice-examples) below.
Language code. Defaults to `"ar"` (Arabic).
Whether to use mu-law audio encoding.
Output sample rate of the PCM audio. One of `8k` or `16k`. Only applies to PCM output — cannot be combined with `mulaw` (mu-law output is always 8 kHz).
Controls how expressive the generated speech sounds, from `0` (flat and monotone) to `2` (highly expressive).
### Example Request
```json theme={null}
{
"type": "tts",
"payload": {
"text": "مرحبا بك في خدمة همسة",
"speaker": "Amjad",
"dialect": "pls",
"languageId": "ar",
"mulaw": false,
"sampleRate": "16k",
"expressiveness": 1
}
}
```
### Response Flow
Server confirms the request was received:
```json theme={null}
{
"type": "ack",
"payload": {
"message": "Real time text to speach connection establesh"
}
}
```
Server streams raw audio data as binary chunks. Buffer these chunks to reconstruct the complete audio file.
Server signals completion:
```json theme={null}
{
"type": "end",
"payload": {
"message": "End of TTS stream"
}
}
```
### Code Example
```javascript JavaScript theme={null}
const ws = new WebSocket('wss://api.tryhamsa.com/v1/realtime/ws?api_key=YOUR_API_KEY');
const audioChunks = [];
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'tts',
payload: {
text: 'مرحبا بك',
speaker: 'Amjad',
dialect: 'pls',
languageId: 'ar',
mulaw: false,
expressiveness: 1
}
}));
};
ws.onmessage = (event) => {
if (event.data instanceof Blob) {
// Binary audio chunk
audioChunks.push(event.data);
} else {
const message = JSON.parse(event.data);
if (message.type === 'end') {
// Combine all chunks into final audio
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
const audioUrl = URL.createObjectURL(audioBlob);
const audio = new Audio(audioUrl);
audio.play();
}
}
};
```
```python Python theme={null}
import asyncio
import websockets
import json
async def tts_stream():
uri = "wss://api.tryhamsa.com/v1/realtime/ws?api_key=YOUR_API_KEY"
async with websockets.connect(uri) as ws:
# Send TTS request
await ws.send(json.dumps({
"type": "tts",
"payload": {
"text": "مرحبا بك",
"speaker": "Amjad",
"dialect": "pls",
"languageId": "ar",
"mulaw": False,
"expressiveness": 1
}
}))
audio_chunks = []
async for message in ws:
if isinstance(message, bytes):
audio_chunks.append(message)
else:
data = json.loads(message)
if data["type"] == "end":
# Save audio file
with open("output.wav", "wb") as f:
f.write(b"".join(audio_chunks))
break
asyncio.run(tts_stream())
```
### Dialects and Voice Examples
Pick a `speaker` that matches your chosen `dialect`. Voice examples per dialect:
| Dialect | Code | Voice examples |
| ----------- | ----- | -------------- |
| Palestinian | `pls` | Amjad, Khayra |
| Egyptian | `egy` | Zahra, Subhi |
| Syrian | `syr` | Dalal, yara |
| Iraqi | `irq` | Lyali, Fatma |
| Jordanian | `jor` | samah, Shaker |
| Lebanese | `leb` | Carla, Majd |
| Saudi | `ksa` | Maram, Hakeem |
| Emirati | `uae` | Sameh, Amera |
| Bahraini | `bah` | Eyad, Halima |
| Qatari | `qat` | Hessa, Nidal |
| Kuwaiti | `kuw` | Mai, Haidar |
| Omani | `oma` | Aisha, Jaber |
| MSA / Fusha | `msa` | Salem, Tamim |
| English | `en` | Emily, James |
***
## Speech-to-Text (STT)
Transcribe audio to text.
### Request
Must be `"stt"`
Base64-encoded audio data.
Language code for transcription. Defaults to `"ar"` (Arabic).
Enable end-of-speech detection.
Threshold for end-of-speech detection (0.0 to 1.0).
The STT model to use for transcription. One of: `s2`, `s3`.
### Example Request
```json theme={null}
{
"type": "stt",
"payload": {
"audioBase64": "//NExAAAAAANIAcAPABEAEQAQABEAEQARABEA...",
"language": "ar",
"isEosEnabled": true,
"eosThreshold": 0.3,
"model": "s2"
}
}
```
### Response
The server sends the transcribed text directly as a plain string (not JSON):
```text theme={null}
مرحبا بك في خدمة همسة
```
### Code Example
```javascript 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);
}
}
};
```
```python Python theme={null}
import asyncio
import websockets
import json
import base64
async def stt_transcribe():
uri = "wss://api.tryhamsa.com/v1/realtime/ws?api_key=YOUR_API_KEY"
async with websockets.connect(uri) as ws:
# Read audio file
with open("audio.wav", "rb") as f:
audio_data = f.read()
audio_base64 = base64.b64encode(audio_data).decode()
# Send STT request
await ws.send(json.dumps({
"type": "stt",
"payload": {
"audioBase64": audio_base64,
"language": "ar",
"isEosEnabled": True,
"eosThreshold": 0.3
}
}))
# Receive transcription
response = await ws.recv()
print(f"Transcription: {response}")
asyncio.run(stt_transcribe())
```
***
## Error Handling
### Error Response Format
```json theme={null}
{
"type": "error",
"payload": {
"message": "Error description"
}
}
```
### WebSocket Close Codes
| Code | Description |
| ------ | ------------------------------------------------------- |
| `4001` | Authentication failed - invalid or missing API key |
| `4003` | Insufficient funds - project wallet balance is depleted |
| `4500` | Internal authentication error |
| `1000` | Connection closed due to inactivity (60 min timeout) |
| `1001` | Server shutting down |
### Common Errors
| Error | Cause |
| ------------------------------------------------- | ------------------------------------------- |
| `Missing API key in headers or query parameters` | No API key provided |
| `API key is invalid or expired` | Invalid API key |
| `User account is inactive or not found` | Account issue |
| `Project is inactive or not found` | Project issue |
| `Insufficient funds in wallet` | Wallet balance is zero or negative |
| `Invalid message format: missing type or payload` | Malformed message |
| `Unsupported message type: [type]` | Unknown message type |
| `Invalid payload for message type: tts` | TTS validation failed |
| `Invalid payload for message type: stt` | STT validation failed |
| `Voice not owned by user` | Attempting to use unauthorized cloned voice |
***
## Rate Limiting
* **Limit**: 100 requests per 60 seconds per API key
* Exceeding the limit returns: `Rate limit exceeded for this API key`
***
# Speech-to-Text
Source: https://docs.tryhamsa.com/websocket/websocket-stt
Transcribe audio to text via WebSocket
Connect to the WebSocket and send STT requests to transcribe audio into text.
## Quick Start
1. Enter your API key in the authentication field
2. Click **Connect** to establish the WebSocket connection
3. Provide base64-encoded audio data
4. Click **Send** to receive transcription
## Request Message
After connecting, send a JSON message with the following structure:
Must be `"stt"`
Base64-encoded audio data.
Language code for transcription. Defaults to `"ar"` (Arabic).
Enable end-of-speech detection.
Threshold for end-of-speech detection (0.0 to 1.0).
The STT model to use for transcription. One of: `s2`, `s3`. Defaults to `s2`.
```json STT Request theme={null}
{
"type": "stt",
"payload": {
"audioBase64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YQAAAAA=",
"language": "ar",
"isEosEnabled": true,
"eosThreshold": 0.3,
"model": "s2"
}
}
```
## Response Format
```text Transcription Result theme={null}
مرحبا بك في خدمة همسة
```
```json Error Response theme={null}
{
"type": "error",
"payload": {
"message": "Error generating transcription: Audio format not supported"
}
}
```
The transcribed text is returned as a **plain string**, not wrapped in JSON.
## Supported Audio Formats
Any audio format supported by the backend (WAV, MP3, etc.), base64-encoded.
# Text-to-Speech
Source: https://docs.tryhamsa.com/websocket/websocket-tts
Convert text to streaming audio via WebSocket
Connect to the WebSocket and send TTS requests to convert text into streaming audio.
## Quick Start
1. Enter your API key in the authentication field
2. Click **Connect** to establish the WebSocket connection
3. Modify the request payload with your text
4. Click **Send** to receive streaming audio
## Request Message
After connecting, send a JSON message with the following structure:
Must be `"tts"`
The text to synthesize. Maximum 2000 characters.
Voice name (e.g. `Amjad`) or the UUID of a custom cloned voice. Pick a speaker that matches the chosen dialect — see the dialect field below for voice examples.
Dialect to synthesize. One of: `pls`, `egy`, `syr`, `irq`, `jor`, `leb`, `ksa`, `uae`, `bah`, `qat`, `kuw`, `oma`, `msa`, `ar-sa`, `en`. See [Dialects and Voice Examples](#dialects-and-voice-examples) below.
Language code. (e.g., "ar").
Whether to use mu-law audio encoding. (e.g., false)
Output sample rate of the PCM audio. One of `8k` or `16k`. Defaults to `16k`. Only applies to PCM output — cannot be combined with `mulaw` (mu-law output is always 8 kHz).
Controls how expressive the generated speech sounds, from `0` (flat and monotone) to `2` (highly expressive). Defaults to `1`.
```json TTS Request theme={null}
{
"type": "tts",
"payload": {
"text": "مرحبا بك في خدمة همسة",
"speaker": "Amjad",
"dialect": "pls",
"languageId": "ar",
"mulaw": false,
"sampleRate": "16k",
"expressiveness": 1
}
}
```
## Response Sequence
The server responds with:
```json 1. Acknowledgment theme={null}
{
"type": "ack",
"payload": {
"message": "Real time text to speach connection establesh"
}
}
```
```json 2. Binary Audio Chunks theme={null}
// Raw binary audio data streamed in chunks
// Buffer these chunks to reconstruct the complete audio
```
```json 3. Stream End theme={null}
{
"type": "end",
"payload": {
"message": "End of TTS stream"
}
}
```
## Dialects and Voice Examples
Pick a `speaker` that matches your chosen `dialect`. Voice examples per dialect:
| Dialect | Code | Voice examples |
| ------------- | ------- | -------------- |
| Palestinian | `pls` | Amjad, Layan |
| Egyptian | `egy` | Mariam, Samir |
| Syrian | `syr` | Dalal, Mais |
| Iraqi | `irq` | Lyali, Fatma |
| Jordanian | `jor` | Lana, Jasem |
| Lebanese | `leb` | Carla, Majd |
| Saudi | `ksa` | Hiba, Fahd |
| Emirati | `uae` | Salma, Dima |
| Bahraini | `bah` | Mazen, Ruba |
| Qatari | `qat` | Deema, Faisal |
| Kuwaiti | `kuw` | Mai, Hatem |
| Omani | `oma` | Aisha, Jaber |
| MSA / Fusha | `msa` | Salem, Tamim |
| Arabic – Gulf | `ar-sa` | Khalid, Rahma |
| English | `en` | Emma, James |
## Available Speakers
Refer to Hamsa Platforms to get the list of the available pre-built speakers where you can take the name of the speaker, or use a UUID for your custom cloned voice.
## Using Custom Cloned Voices
When using a custom cloned voice (UUID) as the speaker, you must preload the voice before establishing the WebSocket connection. This ensures optimal latency during streaming.
**Preload Required for Custom Voices**
Call the [Preload Voice endpoint](/developers/apis/use-cloned-voice-id-as-speaker) once when your application starts to avoid latency when using custom cloned voices.
```javascript theme={null}
// 1. Preload the custom voice at app startup
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: 'your-custom-voice-uuid' })
});
// 2. Now connect to WebSocket and use the custom voice
const ws = new WebSocket('wss://api.tryhamsa.com/v1/realtime/ws?api_key=YOUR_API_KEY');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'tts',
payload: {
text: 'Hello from my custom voice',
speaker: 'your-custom-voice-uuid', // Use the same UUID
dialect: 'pls',
languageId: 'ar',
mulaw: false
}
}));
};
```