How to create a call me form with Laravel to send lead to Vicidial

Fermin Perdomo Fermin Perdomo
schedule 7 min read

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:

  1. Configure the Vicidial API connection.
  2. 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.


Reactions

lock You need to be logged in to react.
Log In

Newsletter

Get new posts delivered straight to your inbox.

mail

Great Tools for Developers

Git Tower

Git Tower

A powerful Git client for Mac and Windows that simplifies version control.

Visit arrow_forward
Mailcoach

Mailcoach

Self-hosted email marketing platform for sending newsletters and automated emails.

Visit arrow_forward
Uptimia

Uptimia

Website monitoring and performance testing tool to ensure your site is always up and running.

Visit arrow_forward
Cloudways

Cloudways

Managed cloud hosting platform that simplifies server management for developers.

Visit arrow_forward

Comments

No comments yet. Be the first to share your thoughts.

chat_bubble Join the conversation — log in to leave a comment.
Log In