How to create a call me form with Laravel to send lead to Vicidial
Fermin Perdomo
Capture Leads in Laravel and Send to Vicidial
Let’s create a simple lead capture form in PHP and send submissions to Vicidial using:
- 🧱 Laravel (PHP framework)
- 📦 Composer (PHP package manager)
- 🖥️ Vicidial (one of the best contact center software in the world)
✅ Prerequisites
Ensure the following are installed on your system:
- PHP (v8.0 or higher)
- Composer (v2.5 or higher)
- A Vicidial server (installed and accessible)
🛠️ Step 1: Create a New Laravel Project
Open your terminal and run:
laravel new callme-vicidial cd callme-vicidial
This may take a few moments. Once it's done, you’ll be inside the new Laravel project directory.
📦 Step 2: Install the Vicidial API Wrapper
We’ll use the masterfermin02/vicidial-api-wrapper package to connect Laravel with Vicidial.
Install it using Composer:
composer require masterfermin02/vicidial-api-wrapper
✏️ Step 3: Code the Application
We'll complete the app in two steps:
- Configure the Vicidial API connection.
- Create the web form in our Laravel app.
🔐 Vicidial Configuration
We recommend creating a dedicated API user in your Vicidial server.
Make sure this user has permission to modify leads/lists.
Now, open your .env file and add your Vicidial credentials:
VICIDIAL_API_USER={your_api_user}
VICIDIAL_API_PASSWORD={your_password}
VICIDIAL_API_URL={http://your-vicidial-server/agc/api.php}
Replace values inside {} with your actual Vicidial data.
🧮 Step 4: Create the Web Form
1. Create a Controller
Run the following command:
php artisan make:controller VicidialLeadController
2. Define the Route
Open routes/web.php and add:
use App\Http\Controllers\VicidialLeadController;
Route::get('/', [VicidialLeadController::class, 'index']);
Route::post('/leads', [VicidialLeadController::class, 'store'])->name('leads.store');
3. Add Controller Logic
Open app/Http/Controllers/VicidialLeadController.php and update:
use Illuminate\Http\Request;
use masterfermin02\VicidialApiWrapper\Vicidial;
class VicidialLeadController extends Controller
{
public function index()
{
return view('pages.vicidial.admin.lead');
}
public function store(Request $request)
{
$vicidial = new Vicidial();
$vicidial->addLead([
'phone_number' => $request->input('phone'),
'first_name' => $request->input('name'),
'list_id' => 999, // Change this if needed
]);
return redirect('/')->with('success', 'Lead sent to Vicidial!');
}
}
4. Create the View
Inside resources/views, create folders:
pages/vicidial/admin/
Then, inside admin, create the file: lead.blade.php
Paste the HTML from this Gist:
<!doctype html>
<html>
<head>
<title>Lead</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="font-sans text-gray-900 antialiased relative isolate px-6 pt-14 lg:px-8">
<form method="post" action="{{ url('/vicidial/admin/lead') }}">
@csrf
<div class="space-y-12">
<div class="border-b border-gray-900/10 pb-12">
<h2 class="text-base font-semibold leading-7 text-gray-900">Vicidial form</h2>
</div>
<div class="border-b border-gray-900/10 pb-12">
<h2 class="text-base font-semibold leading-7 text-gray-900">Personal Information</h2>
<p class="mt-1 text-sm leading-6 text-gray-600">Use a permanent address where you can receive mail.</p>
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-3">
<label for="first-name" class="block text-sm font-medium leading-6 text-gray-900">First name</label>
<div class="mt-2">
<input type="text" name="first-name" id="first-name" autocomplete="given-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div class="sm:col-span-3">
<label for="last-name" class="block text-sm font-medium leading-6 text-gray-900">Last name</label>
<div class="mt-2">
<input type="text" name="last-name" id="last-name" autocomplete="family-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div class="sm:col-span-4">
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
<div class="mt-2">
<input id="email" name="email" type="email" autocomplete="email" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div class="sm:col-span-3">
<label for="country" class="block text-sm font-medium leading-6 text-gray-900">Country</label>
<div class="mt-2">
<select id="country" name="country" autocomplete="country-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6">
<option>United States</option>
<option>Canada</option>
<option>Mexico</option>
<option>Dominican Republic</option>
</select>
</div>
</div>
<div class="col-span-full">
<label for="street-address" class="block text-sm font-medium leading-6 text-gray-900">Street address</label>
<div class="mt-2">
<input type="text" name="street-address" id="street-address" autocomplete="street-address" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div class="sm:col-span-2 sm:col-start-1">
<label for="city" class="block text-sm font-medium leading-6 text-gray-900">City</label>
<div class="mt-2">
<input type="text" name="city" id="city" autocomplete="address-level2" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div class="sm:col-span-2">
<label for="region" class="block text-sm font-medium leading-6 text-gray-900">State / Province</label>
<div class="mt-2">
<input type="text" name="region" id="region" autocomplete="address-level1" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div class="sm:col-span-2">
<label for="postal-code" class="block text-sm font-medium leading-6 text-gray-900">ZIP / Postal code</label>
<div class="mt-2">
<input type="text" name="postal-code" id="postal-code" autocomplete="postal-code" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div class="sm:col-span-2">
<label for="phone_number" class="block text-sm font-medium leading-6 text-gray-900">Phone number</label>
<div class="mt-2">
<input type="text" name="phone_number" id="phone_number" autocomplete="tel" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
</div>
</div>
</div>
<div class="mt-6 flex items-center justify-end gap-x-6">
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
</div>
</form>
</div>
</body>
</html>🌐 Test It
Visit http://your-app-url/ in your browser.
- Fill out the form
- Click Save
- The lead should now appear in Vicidial list 999 (or your specified list)
📁 Full Example
You can download the complete example from GitHub:
🔗 https://github.com/masterfermin02/callme-example-for-vicidial
🧾 Conclusion
In this guide, we learned how to:
- Set up a Laravel app
- Create a controller and define routes
- Configure Vicidial API credentials
- Use the vicidial-api-wrapper to send leads
This setup is ideal for creating lightweight landing pages or simple CRMs that sync with Vicidial in real time.
Newsletter
Get new posts delivered straight to your inbox.
Great Tools for Developers
Git Tower
Get Started - It's FreeA powerful Git client for Mac and Windows that simplifies version control.
Mailcoach
Start freeSelf-hosted email marketing platform for sending newsletters and automated emails.
Uptimia
Start freeWebsite monitoring and performance testing tool to ensure your site is always up and running.
Cloudways
Start freeManaged cloud hosting platform that simplifies server management for developers.
Comments
No comments yet. Be the first to share your thoughts.