Overview
TelemanAI integrates with VAPI to provide advanced AI voice assistant capabilities. Create intelligent conversational agents that can handle customer inquiries, qualify leads, schedule appointments, and more - all with natural, human-like voice interactions.
Natural Conversations AI-powered conversations that understand context and intent
Multiple AI Models Support for OpenAI, Azure OpenAI, and more
Voice Customization Choose from multiple voice providers and voices
Knowledge Base Upload documents to train your assistant
Getting Started
VAPI Configuration
Before creating AI assistants, configure your VAPI API keys:
// From VapiController.php:70-86 - Setup VAPI Keys
public function setupStore ( Request $request )
{
if ( demo ()) {
smilify ( 'warning' , 'This feature is disabled in demo mode' );
return back ();
}
overWriteEnvFile ( 'VAPI_API_KEY' , $request -> vapi_api_key );
overWriteEnvFile ( 'VAPI_PUBLIC_KEY' , $request -> vapi_public_key );
activity ( 'voice ai' , 'updated vapi api key' );
smilify ( 'success' , 'Vapi api key updated successfully' );
Artisan :: call ( 'optimize:clear' );
return back ();
}
Get VAPI Keys
Sign up at VAPI.ai and obtain your API keys
Configure Keys
Enter your VAPI API Key and Public Key in the Voice AI setup page
Connect Twilio
Link your Twilio provider to enable phone number integration
Create Assistant
Build your first AI voice assistant
Creating AI Assistants
Basic Configuration
Create a new AI assistant with essential settings:
// From VapiController.php:156-301 - Create Assistant
public function createAssistant ( Request $request )
{
$data = [
'name' => $request -> name ,
'firstMessage' => $request -> firstMessage ,
'voicemailDetectionEnabled' => filter_var ( $request -> input ( 'voicemailDetectionEnabled' ), FILTER_VALIDATE_BOOLEAN ),
'voicemailMessage' => $request -> voicemailMessage ,
'endCallMessage' => $request -> endCallMessage ,
// Transcriber configuration
'transcriber' => [
'provider' => $request -> input ( 'transcriber.provider' , 'deepgram' ),
'model' => $request -> input ( 'transcriber.model' , 'nova-2-general' ),
'language' => 'en' ,
'keywords' => []
],
// AI Model configuration
'model' => [
'model' => $request -> model [ 'model' ],
'messages' => [
[
'content' => $request -> summaryPrompt ,
'role' => 'system'
]
],
'provider' => $request -> model [ 'provider' ],
'emotionRecognitionEnabled' => true ,
'temperature' => floatval ( $request -> input ( 'model.temperature' , 0.7 )),
'maxTokens' => intval ( $request -> input ( 'model.maxTokens' , 500 )),
],
// Voice configuration
'voice' => [
'provider' => $request -> voice [ 'provider' ],
'voiceId' => $request -> voice [ 'voiceId' ]
],
'recordingEnabled' => true ,
];
$response = $this -> vapiService -> createAssistant ( $data );
VapiAssistant :: updateOrCreate (
[ 'slug' => Str :: slug ( $request -> name ), 'user_id' => auth () -> id ()],
[
'name' => $response [ 'name' ],
'assistantId' => $response [ 'id' ],
'data' => json_encode ( $data ),
'response' => json_encode ( $response )
]
);
}
Assistant Configuration Options
model : {
provider : 'openai' , // openai, azure-openai, together-ai, anyscale, openrouter
model : 'gpt-4' , // Specific model version
temperature : 0.7 , // Creativity (0.0-1.0)
maxTokens : 500 , // Max response length
emotionRecognitionEnabled : true ,
semanticCachingEnabled : true // Cache common responses
}
Temperature Guide:
0.0-0.3: Focused and deterministic
0.4-0.7: Balanced creativity
0.8-1.0: Creative and varied
Choose from multiple voice providers:
ElevenLabs - High-quality, natural voices
PlayHT - Professional voice library
Rime - Fast, efficient voices
Deepgram - Low-latency voices
Each provider offers multiple voice IDs for different tones and accents.
transcriber : {
provider : 'deepgram' , // deepgram, gladia, talkscriber
model : 'nova-2-general' , // Transcription model
language : 'en' , // Language code
keywords : [] // Custom keywords for accuracy
}
Recommended: Use Deepgram’s nova-2-general for best accuracy.
Advanced Features
Knowledge Base Integration
Upload documents to train your assistant:
// From VapiController.php:121-148 - Upload Knowledge Base Files
public function fileUpload ( Request $request )
{
$request -> validate ([
'file' => 'required|mimes:pdf,txt,docx|max:2048' ,
]);
$file = $request -> file ( 'file' );
$uploadResponse = $this -> vapiService -> uploadFile ( $file );
if ( isset ( $uploadResponse [ 'error' ])) {
return back () -> withErrors ([ 'error' => 'Failed to upload file: ' . $uploadResponse [ 'error' ]]);
}
VapiFiles :: create ([
'file_id' => $uploadResponse [ 'id' ],
'file_name' => $uploadResponse [ 'name' ],
'url' => $uploadResponse [ 'url' ],
'bytes' => $uploadResponse [ 'bytes' ],
'mimetype' => $uploadResponse [ 'mimetype' ],
'path' => $uploadResponse [ 'path' ],
'user_id' => auth () -> id (),
]);
smilify ( 'success' , 'File uploaded and saved successfully.' );
return back ();
}
Upload Documents
Upload PDF, TXT, or DOCX files containing information for your assistant
Link to Assistant
Add the file IDs to your assistant’s knowledge base configuration
Test Knowledge
Make test calls to verify the assistant can retrieve information from your documents
Call Forwarding
Configure your assistant to forward calls to human agents:
// From VapiController.php:242-258 - Forwarding Configuration
if ( $request -> has ( 'callForwarding' )) {
$forwardingPhoneNumbers = [];
foreach ( $request -> forwardingPhoneNumbers as $index => $phoneNumber ) {
$forwardingPhoneNumbers [] = [
'number' => $phoneNumber ,
'message' => $request -> forwardingMessages [ $index ],
'sipUri' => null
];
}
$data [ 'forwardingPhoneNumbers' ] = $forwardingPhoneNumbers ;
// Backward compatibility
if ( ! empty ( $forwardingPhoneNumbers )) {
$data [ 'forwardingPhoneNumber' ] = $forwardingPhoneNumbers [ 0 ][ 'number' ];
}
}
Your assistant can intelligently forward calls based on conversation context, keywords, or customer requests.
Timing Configuration
Fine-tune conversation timing:
// From VapiController.php:220-225 - Timing Settings
'silenceTimeoutSeconds' => intval ( $request -> input ( 'silenceTimeoutSeconds' , 30 )),
'responseDelaySeconds' => floatval ( $request -> input ( 'responseDelaySeconds' , 1.0 )),
'llmRequestDelaySeconds' => 0.1 ,
'numWordsToInterruptAssistant' => intval ( $request -> input ( 'numWordsToInterruptAssistant' , 2 )),
'maxDurationSeconds' => intval ( $request -> input ( 'maxDurationSeconds' , 600 )),
Setting Default Description silenceTimeoutSeconds30 How long to wait for customer response responseDelaySeconds1.0 Pause before assistant responds numWordsToInterruptAssistant2 Words needed to interrupt AI maxDurationSeconds600 Maximum call duration (10 minutes)
Call Experience Settings
// From VapiController.php:228-231 - Experience Settings
'backgroundSound' => $this -> validateBackgroundSound ( $request -> input ( 'backgroundSound' , 'office' )),
'endCallPhrases' => $request -> filled ( 'endCallPhrases' )
? array_map ( 'trim' , explode ( ',' , $request -> endCallPhrases ))
: [ 'goodbye' , 'thank you' , 'have a great day' ],
Add ambient sound for realism:
off - No background sound
office - Office environment sounds
Custom URL - Upload your own background audio
Making AI-Powered Calls
Initiate Outbound Calls
Start AI-powered calls programmatically:
// From VapiController.php:88-113 - Create Phone Call
public function createPhoneCall ( Request $request )
{
$validatedData = $request -> validate ([
'phone' => 'required|string' ,
'provider_phone' => 'required|string' ,
'assistantId' => 'required|string' ,
]);
$callData = [
'maxDurationSeconds' => 10 ,
'assistantId' => $validatedData [ 'assistantId' ],
'customer' => [
'number' => $validatedData [ 'phone' ],
'name' => $validatedData [ 'phone' ]
],
'phoneNumber' => [
'twilioAccountSid' => getProvider ( auth () -> id (), $validatedData [ 'provider_phone' ]) -> account_sid ,
'twilioAuthToken' => getProvider ( auth () -> id (), $validatedData [ 'provider_phone' ]) -> auth_token ,
'twilioPhoneNumber' => getProvider ( auth () -> id (), $validatedData [ 'provider_phone' ]) -> phone
]
];
$call = $this -> vapiService -> createPhoneCall ( $callData );
smilify ( 'success' , 'Call Queued Successfully' );
return back ();
}
Phone Number Integration
Link Twilio Numbers to Assistants
Connect your Twilio phone numbers to AI assistants:
// From VapiController.php:461-486 - Create Phone Number
public function createPhoneNumber ( $provider_id )
{
try {
$provider = getProviderById ( $provider_id );
if ( ! $provider ) {
smilify ( 'error' , 'Provider not found' );
return back ();
}
$data = [
'provider' => 'twilio' ,
'number' => $provider -> phone ,
'twilioAccountSid' => $provider -> account_sid ,
'twilioAuthToken' => $provider -> auth_token ,
'name' => $provider -> provider_name
];
$phoneNumber = $this -> vapiService -> createPhoneNumber ( $data );
return back () -> with ( 'success' , 'Phone number created successfully.' );
} catch ( \ Exception $e ) {
smilify ( 'error' , 'Failed to create phone number.' );
return back ();
}
}
Update Phone Number Settings
Assign assistants to specific phone numbers:
// From VapiController.php:35-50 - Update Phone Number
public function phone_number_update ( Request $request , $phoneNumberId )
{
$data = [
'fallbackDestination' => [
'type' => 'number' ,
'number' => $request -> input ( 'number' )
],
'name' => $request -> input ( 'name' ),
'assistantId' => $request -> input ( 'assistantId' )
];
$this -> vapiService -> updatePhoneNumber ( $phoneNumberId , $data );
smilify ( 'success' , 'Phone number updated successfully' );
return back ();
}
When a call comes to your Twilio number, it will automatically route to the assigned AI assistant.
Call Logs and Analytics
View Call History
Access detailed logs of all AI-powered calls:
// From VapiController.php:19-26 - Dashboard with Call Logs
public function index ()
{
$callLogs = collect ( $this -> vapiService -> listCalls ()) -> sortByDesc ( 'createdAt' ) -> toArray ();
$reportService = new VapiReportService ( $callLogs );
return view ( 'backend.voiceai.index' , [
'reportService' => $reportService ,
]);
}
Individual Call Details
// From VapiController.php:58-63 - Get Call Details
public function call_logs ( $id = null )
{
$calls = collect ( $this -> vapiService -> listCalls ()) -> sortByDesc ( 'createdAt' ) -> toArray ();
$getCall = $id === null ? null : $this -> vapiService -> getCall ( $id );
return view ( 'backend.voiceai.call_logs.index' , compact ( 'calls' , 'getCall' ));
}
Call logs include:
Transcript - Full conversation transcript
Duration - Call length
Cost - Call cost breakdown
Sentiment - Detected customer sentiment
Summary - AI-generated call summary
Recording - Audio recording URL
Assistant Data Structure
-- From migrations/2024_06_02_131108_create_vapi_assistants_table.php
CREATE TABLE vapi_assistants (
id BIGINT UNSIGNED PRIMARY KEY ,
slug VARCHAR ( 255 ), -- URL-friendly identifier
user_id BIGINT UNSIGNED, -- Owner
assistantId TEXT , -- VAPI assistant ID
data JSON , -- Configuration data
response JSON , -- VAPI API response
created_at TIMESTAMP ,
updated_at TIMESTAMP
);
Updating Assistants
Modify existing assistant configuration:
// From VapiController.php:303-447 - Update Assistant
public function updateAssistant ( Request $request , $id )
{
$assistant = VapiAssistant :: where ( 'assistantId' , $id ) -> firstOrFail ();
$data = [
'name' => $request -> name ,
'firstMessage' => $request -> firstMessage ,
// ... same configuration as create ...
'metadata' => [
'updated_by' => auth () -> user () -> name ?? 'system' ,
'updated_at' => now () -> toISOString (),
'version' => '1.1'
]
];
DB :: beginTransaction ();
try {
$response = $this -> vapiService -> updateAssistant ( $id , $data );
if ( isset ( $response [ 'error' ])) {
throw new \Exception ( $response [ 'error' ] ?? 'Unknown error occurred' );
}
$assistant -> update ([
'name' => $response [ 'name' ],
'data' => json_encode ( $data ),
'response' => json_encode ( $response )
]);
DB :: commit ();
smilify ( 'success' , 'Assistant updated successfully.' );
return back ();
} catch ( \ Exception $e ) {
DB :: rollBack ();
smilify ( 'error' , 'Failed to update assistant.' );
return back ();
}
}
Deleting Assistants
// From VapiController.php:449-459 - Delete Assistant
public function deleteAssistant ( $id )
{
try {
$response = $this -> vapiService -> deleteAssistant ( $id );
VapiAssistant :: where ( 'assistantId' , $response [ 'id' ]) -> delete ();
smilify ( 'success' , 'Assistant deleted successfully.' );
return redirect () -> back ();
} catch ( \ Exception $e ) {
return redirect () -> back () -> with ( 'error' , 'Failed to delete assistant.' );
}
}
Deleting an assistant removes it from VAPI and your TelemanAI account. This cannot be undone.
Best Practices
Clear Prompts Write clear, specific system prompts that define your assistant’s personality and capabilities.
Test Thoroughly Make test calls to verify your assistant handles various scenarios correctly.
Monitor Performance Regularly review call logs and transcripts to improve your assistant.
Set Boundaries Define what your assistant can and cannot do in the system prompt.
Use Cases
Create an assistant that asks qualifying questions and routes high-value leads to sales agents. System Prompt Example: You are a friendly lead qualification assistant. Ask about the customer's
business needs, budget, and timeline. If they have a budget over $10,000
and need a solution within 3 months, forward them to a sales representative.
Build an assistant that checks availability and books appointments. System Prompt Example: You are an appointment scheduling assistant. Gather the customer's name,
preferred date and time, and reason for appointment. Check if the requested
time is available and confirm the booking.
Deploy an assistant that answers common questions using your knowledge base. System Prompt Example: You are a customer support assistant. Answer questions about our products
and services using the knowledge base. If you cannot answer a question or
the customer is upset, transfer them to a human agent.
Create an assistant that conducts surveys and collects feedback. System Prompt Example: You are a survey assistant. Ask the customer to rate their recent experience
from 1-10 and provide any feedback. Thank them for their time and end the call.
Voice Campaigns Use AI assistants in automated campaigns
Web Dialer Test your AI assistant with the web dialer
Analytics Analyze AI assistant performance metrics