Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Klaviyo Laravel Package

jeffersongoncalves/laravel-klaviyo

A Laravel integration for Klaviyo, the email and SMS marketing platform. Manage profiles, lists, events, and campaigns through a clean, expressive API, with configuration and service provider support for quick setup in any Laravel application.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and configure:
    composer require <vendor>/laravel-klaviyo
    php artisan vendor:publish --tag=klaviyo-config
    
  2. Add credentials to .env:
    KLAVIYO_API_KEY=pk_xxx
    
  3. Clear cached config after changes:
    php artisan config:clear
    
  4. Look first at:
    • config/klaviyo.php — API key, base URL, timeout, retry/rate-limit settings.
    • The package service provider — confirms how the client is bound into the container and whether a facade alias is registered.
    • The client and resource classes — profiles, lists, events, campaigns, flows, metrics, segments, templates are the initial surface area.

A good first use case is the most common Laravel/Klaviyo workflow: upsert a profile, add it to a list, and track an event.

use App\Models\User;

$klaviyo = app(\Klaviyo\Client::class); // confirm exact binding in the service provider

$profile = $klaviyo->profiles()->upsert([
    'email' => $user->email,
    'first_name' => $user->first_name,
    'last_name' => $user->last_name,
]);

$klaviyo->lists()->addProfiles($listId, [$profile['id']]);

$klaviyo->events()->create([
    'profile' => ['email' => $user->email],
    'metric' => ['name' => 'Started Trial'],
    'properties' => ['plan' => 'pro'],
]);

If the package exposes a facade, prefer dependency injection in application code and reserve the facade for tinker/scripts. Run a single read call first, such as listing segments or metrics, to validate credentials before testing write operations.

Implementation Patterns

Inject the client, not the facade. Bind the package client through the container and inject it into services, jobs, and listeners. This keeps tests swappable and avoids facade coupling.

class KlaviyoSubscriber
{
    public function __construct(private \Klaviyo\Client $klaviyo) {}
}

Wrap writes in queued jobs. Profile upserts, list membership changes, and event tracking should generally be queued. This isolates Klaviyo latency and failures from the request lifecycle and gives you retry/backoff semantics.

TrackKlaviyoEvent::dispatch($user, 'Order Placed', ['order_id' => $order->id])
    ->onQueue('klaviyo');

Use a dedicated integration layer. Keep Klaviyo calls out of controllers and models. A small service such as App\Services\Klaviyo\SubscriberSync makes it easier to enforce consent rules, map local fields, and centralize error handling.

Model Klaviyo resources as read/write boundaries. Profiles, lists, events, and templates are typically write-capable. Campaigns, flows, metrics, and segments are often read-oriented in an API client. Treat reporting resources as read-only unless the package explicitly documents otherwise.

Handle pagination explicitly. List endpoints commonly return cursor-based pagination. Loop until the cursor is exhausted rather than assuming a single response is complete.

$cursor = null;
do {
    $page = $klaviyo->profiles()->all(['page[cursor]' => $cursor]);
    foreach ($page['data'] as $profile) { /* ... */ }
    $cursor = $page['links']['next'] ?? null;
} while ($cursor);

Map local users to Klaviyo profiles deliberately. Decide whether email or an external ID is the canonical identifier, and use the same identifier consistently across profiles, events, and list operations. Store the returned Klaviyo profile ID if you need stable references.

Isolate multi-tenant credentials. If you operate multiple Klaviyo accounts, avoid a single global config. Resolve a client instance per tenant/account with its own API key and configuration rather than mutating global config at runtime.

Test with Laravel’s HTTP fake. Since the package is an API client, assert outgoing requests instead of mocking every resource method:

Http::fake(['api.klaviyo.com/*' => Http::response(['data' => []], 200)]);

// trigger your integration service/job, then assert the request payload
Http::assertSent(fn ($request) => $request['data']['attributes']['email'] === '[email protected]');

Also consider binding a fake client implementation in the container for unit tests of higher-level services.

Use events/listeners for domain workflows. For example, listen to Registered or OrderPlaced and dispatch a Klaviyo job. This keeps Klaviyo concerns out of the registration/checkout path and makes it easy to disable or requeue syncs.

Add observability around integration calls. Log failures with context (endpoint, status, Klaviyo request ID) but never log API keys or full PII payloads. Emit metrics for 4xx/5xx rates so credential or payload issues are visible.

Gotchas and Tips

  • Check the API revision/versioning strategy. Klaviyo APIs are versioned; confirm whether the package pins a revision, exposes it in config, or allows overriding headers. An unpinned client can break when Klaviyo changes defaults.
  • Rate limits are real. Klaviyo enforces burst and steady-state limits. Rely on the package’s retry middleware if present, and back off on 429. Do not retry aggressively inside synchronous requests.
  • IDs are strings. Klaviyo profile, list, and event IDs should be treated as opaque strings. Do not cast them to integers or assume numeric ordering.
  • Event tracking is asynchronous downstream. A successful event API call does not mean the event immediately appears in metrics, segments, or flows. Avoid building user-facing logic that assumes instant consistency.
  • Profile upsert semantics matter. Ensure you understand whether the package’s profile method creates, updates, or merges by email/external ID. Duplicate profiles are usually caused by inconsistent identifiers, not by the client.
  • Consent is an application concern. The API client will happily send profiles and events; your app must enforce marketing consent, double opt-in, and GDPR deletion requirements before calling Klaviyo.
  • Config caching catches people out. After changing KLAVIYO_API_KEY or related env values in a cached deployment, run php artisan config:cache as part of deploy. Local config:clear fixes most “why is it using the old key” issues.
  • Timeouts and connection failures need handling. Set explicit timeouts in config and catch transport exceptions. A slow Klaviyo API should not hold a web request open.
  • Inspect the actual exception types. The package may throw its own exception classes or surface Laravel HTTP client exceptions. Catch the package’s documented exception type where possible, and inspect response bodies for Klaviyo’s validation errors.
  • 1.0.0 is an initial release. Expect API surface changes as the package matures. Pin the version in composer.json and review changelogs before minor upgrades. There is no prior assessment to compare against, so treat this release as the baseline.
  • Extension points to check: custom HTTP client/middleware configuration, configurable base URL (useful for testing), container binding override, and whether resources are resolved lazily. These determine how easily you can add logging, retries, or per-tenant clients.
  • Do not assume every Klaviyo endpoint is covered. The release notes list profiles, lists, events, campaigns, flows, metrics, segments, and templates. If you need catalog, coupons, or webhooks, verify support before designing around the package.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console