How to create a call me form with Laravel to send lead to Vicidial
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.
Please login to leave a comment.