Skip to content

Configuration reference

Every env variable + every config key. Defaults in bold.

The published config file is config/laravel-whatsapp.php. Re-publish on upgrade if new keys are added (Laravel's mergeConfigFrom is shallow and won't merge nested keys into your existing copy):

bash
php artisan vendor:publish --tag=laravel-whatsapp-config --force

Cloud API

Env varDefaultPurpose
WHATSAPP_BASE_HOSTgraph.facebook.comMeta Graph API host
WHATSAPP_API_VERSIONv21.0Graph API version
WHATSAPP_PHONE_NUMBER_IDrequiredFrom WhatsApp → API Setup
WHATSAPP_BUSINESS_ACCOUNT_IDrequiredWABA ID
WHATSAPP_ACCESS_TOKENrequiredPermanent System User token
WHATSAPP_TIMEOUT30HTTP timeout to Meta in seconds

Webhook receiver

Env varDefaultPurpose
WHATSAPP_WEBHOOK_ENABLEDtrueRegister the webhooks/whatsapp routes
WHATSAPP_WEBHOOK_ROUTEwebhooks/whatsappURL path (no leading slash)
WHATSAPP_VERIFY_TOKENrequiredRandom string — also enter in Meta's webhook config
WHATSAPP_APP_SECRETrequiredFrom Meta App Settings → Basic. HMAC-verifies every POST
WHATSAPP_VERIFY_SIGNATUREtrueSet false for local testing with ngrok

Middleware on the routes is ['api'] by default. Override in config/laravel-whatsapp.phpwebhook.middleware.

Web sidecar

Env varDefaultPurpose
WHATSAPP_WEB_ENABLEDfalseToggle the Web backend on
WHATSAPP_WEB_HOST127.0.0.1Interface the sidecar binds to. See host details below
WHATSAPP_WEB_PORT3000Sidecar port (used for both bind + Laravel connection)
WHATSAPP_WEB_TOKENemptyShared bearer token for Laravel↔sidecar auth. Set in production
WHATSAPP_WEB_TIMEOUT60HTTP timeout (seconds) for sidecar calls

Sidecar process

Env varDefaultPurpose
WHATSAPP_WEB_SIDECAR_PATHvendor/kstmostofa/laravel-whatsapp/sidecarWhere the Node service lives
WHATSAPP_WEB_NODE_BINARYnodePath to Node binary
WHATSAPP_WEB_NPM_BINARYnpmPath to npm
WHATSAPP_WEB_SESSION_DIRstorage/app/whatsapp-sidecar/sessionsPersisted WhatsApp Web auth state
WHATSAPP_WEB_PID_FILEstorage/app/whatsapp-sidecar/sidecar.pidPID file
WHATSAPP_WEB_LOG_FILEstorage/logs/whatsapp-sidecar.logstdout log
WHATSAPP_WEB_ERR_FILEstorage/logs/whatsapp-sidecar.err.logstderr log

Why 127.0.0.1?

Default = 127.0.0.1 because the sidecar runs on the same server as Laravel and is reached over loopback. The sidecar holds your WhatsApp session — exposing it on 0.0.0.0 without auth = anyone on the network can send messages from your account.

TopologyWHATSAPP_WEB_HOST
Laravel + sidecar same server (default)127.0.0.1
Sidecar on another machinesidecar machine's IP, e.g. 10.0.0.5 + STRONG WHATSAPP_WEB_TOKEN + firewall
Behind a reverse proxy on a subdomainhostname of the proxy + TLS

WHATSAPP_WEB_HOST is unrelated to your Laravel APP_URL. Don't set it to your public domain unless the sidecar is actually reachable there.

UI

Env varDefaultPurpose
WHATSAPP_UI_ENABLEDtrueRegister the UI routes (also needs livewire/flux installed)
WHATSAPP_UI_PREFIXwhatsappURL prefix — /whatsapp/* becomes /<prefix>/*
WHATSAPP_UI_DEFAULT_SESSIONmainDefault session ID used when ?session= isn't in the URL
WHATSAPP_UI_POLL_INTERVAL5swire:poll interval on the conversations page
WHATSAPP_UI_CSS_MODEvitevite | standalone | none. See UI install paths
WHATSAPP_UI_CHAT_LIST_LIMIT50Max chats rendered in the conversations sidebar (0 = unlimited)
WHATSAPP_UI_MESSAGES_INITIAL50Messages loaded per chat on first open
WHATSAPP_UI_MESSAGES_PAGE_SIZE50Per "Load older messages" click
WHATSAPP_UI_CHATS_CACHE_SECONDS3Cache the sidecar chats list this long (poll absorber)
WHATSAPP_UI_CONTACTS_CACHE_SECONDS30Cache the sidecar contacts list this long

Middleware on UI routes is ['web'] by default — wrap in your own auth before production:

php
// config/laravel-whatsapp.php
'ui' => [
    'middleware' => ['web', 'auth', 'can:manage-whatsapp'],
    // …
],

Database

Env varDefaultPurpose
WHATSAPP_DB_CONNECTIONempty (uses app default)Key from config/database.php. Lets you isolate WA data on a separate DB
WHATSAPP_DB_PREFIXemptyPrepended to wa_sessions, wa_messages, wa_contacts

Models (WaSession, WaMessage, WaContact) use the UsesWhatsAppConnection trait — they read both keys at runtime, so changing them in .env is enough; no model rebuild.

Migrations also resolve the connection + prefix at migration time:

php
Schema::connection(config('laravel-whatsapp.database.connection'))
    ->create(config('laravel-whatsapp.database.prefix', '').'wa_sessions', );

Example multi-DB setup in config/database.php:

php
'connections' => [
    'mysql' => [],                           // your main app DB
    'whatsapp' => [                           // dedicated for WA data
        'driver' => 'pgsql',
        'host' => env('WHATSAPP_DB_HOST'),
        'port' => env('WHATSAPP_DB_PORT', 5432),
        'database' => env('WHATSAPP_DB_DATABASE'),
        'username' => env('WHATSAPP_DB_USERNAME'),
        'password' => env('WHATSAPP_DB_PASSWORD'),
    ],
],

Drivers can differ — your app on MySQL, WhatsApp on Postgres, no problem.

Persistence

Env varDefaultPurpose
WHATSAPP_PERSIST_INCOMINGfalseAuto-write inbound messages + ack updates to wa_messages

When true, the package registers PersistIncomingMessage as a listener for both Cloud and Web backends. Idempotent — re-delivered messages don't duplicate.

Broadcasting

Env varDefaultPurpose
WHATSAPP_BROADCASTfalseMake Web events implement ShouldBroadcast
WHATSAPP_BROADCAST_PREFIXwhatsappChannel prefix, e.g. whatsapp.session.main
WHATSAPP_BROADCAST_CHANNELpublicpublic or private

When broadcasting is on, Events\Web\MessageReceived, QrGenerated, MessageAck are pushed over your configured broadcaster (Reverb / Pusher / Ably). The UI uses wire:poll by default — flip this if you want sub-second updates instead.

Queue

Env varDefaultPurpose
WHATSAPP_QUEUE_CONNECTIONLaravel defaultQueue connection for SendMessage job
WHATSAPP_QUEUEdefaultQueue name

Full config file

After php artisan vendor:publish --tag=laravel-whatsapp-config, you'll have a fully-commented config/laravel-whatsapp.php in your project. Comments in there are the source of truth for every option.

Released under the MIT License.