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

Mailjet Bundle Laravel Package

welp/mailjet-bundle

Symfony bundle for integrating the Mailjet email API, providing configurable transport, event handling, and Laravel-style mailer support.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before you install anything. welp/mailjet-bundle is a Symfony bundle for the Mailjet Send API v3, last released in June 2019. It is not a Laravel package: it has no service provider, no facade, no config publish tag, and it is wired through Symfony's DI container and bundle extension. In a Laravel app you should not install it — you get the same functionality in about 15 lines by binding the underlying SDK (mailjet/mailjet-apiv3-php) as a singleton. Treat this bundle as a reference implementation and only install it if you are actually on Symfony 3.4/4.x.

Where to look first in the source:

  1. DependencyInjection/Configuration.php — the real config keys (api_key/secret_key naming varies by tag; older docs say public_key/private_key).
  2. DependencyInjection/*Extension.php and Resources/config/services.* — the service IDs and whether the client service is public or private.
  3. The transport class (Swiftmailer-era) — useful only if you are on old Symfony.
  4. composer.json — check the symfony/* and PHP constraints before wasting time; there is no Flex recipe.

Symfony path (the package's intended use):

composer require welp/mailjet-bundle mailjet/mailjet-apiv3-php
# register manually in config/bundles.php if there is no recipe
bin/console config:dump-reference welp_mailjet   # confirm key names for your tag
bin/console debug:container --show-private | grep -i mailjet
# config/packages/welp_mailjet.yaml
welp_mailjet:
    api_key: '%env(MAILJET_API_KEY)%'
    secret_key: '%env(MAILJET_SECRET_KEY)%'
    sandbox: false

Then inject the bundle's client/transport service into one small WelcomeMailer-style class rather than calling the container.

Laravel path (recommended): skip the bundle. Install the SDK and bind it once.

composer require mailjet/mailjet-apiv3-php
// app/Providers/MailjetServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Mailjet\Client::class, fn () => new \Mailjet\Client(
        config('services.mailjet.key'),
        config('services.mailjet.secret'),
        true,
        ['version' => 'v3.1']
    ));
}

First use case: one transactional email (welcome or password reset) in Mailjet sandbox mode, asserting the response object, before wiring templates or queues.

Implementation Patterns

Wrap the client, don't scatter payload arrays. The bundle is thin; its value is DI wiring, not abstractions. Put payload construction in one place (a MailjetNotifier or per-notification classes) and keep controllers/jobs ignorant of Mailjet's array shape.

$response = $this->mailjet->post(Resources::EMAIL_SEND, [
    'body' => ['Messages' => [[
        'From'     => ['Email' => '[email protected]', 'Name' => 'Acme'],
        'To'       => [['Email' => $user->email, 'Name' => $user->name]],
        'Subject'  => 'Welcome',
        'HTMLPart' => view('emails.welcome', compact('user'))->render(),
        'TextPart' => 'Welcome!',
        'CustomID' => 'welcome:'.$user->id,
    ]]],
]);

if (! $response->success()) {
    throw new RuntimeException($response->getReasonPhrase());
}

Templated sends. For anything designed in Mailjet's editor, send TemplateID + TemplateLanguage => true + a Variables map instead of HTML. This is the pattern that makes the bundle worth having a wrapper for: your app emits domain data, Mailjet owns markup.

Batch and queue. Send API v3.1 accepts a Messages array (up to 50 per call). For anything user-triggered, dispatch a queued job (ShouldQueue in Laravel, Messenger in Symfony) and chunk recipient lists. Pass CustomID on every message so you can correlate the Mailjet event log and webhooks back to a row in your database.

Sandbox in dev/test. Either the bundle's config flag (if your tag has one) or per-request 'SandboxMode' => true in the body. It still validates the payload and returns 200, so it is the right way to test payload shape in CI — but it never delivers mail, so do not rely on it to catch template/variable errors.

Transport integration. Older tags ship a Swiftmailer transport so swiftmailer.mailer.default.transport can route through Mailjet. That is only relevant on Symfony 3.4/4.x with Swiftmailer (EOL). On modern Symfony use symfony/mailer with the Mailjet bridge if available, or bypass mailer abstractions and call the client directly. In Laravel, calling the client directly from a queued job is simpler and more debuggable than writing a custom Mail transport.

Webhooks/events are yours to build. The bundle does not handle Mailjet's event webhooks (opens, bounces, spam, blocked). Add a route, verify the request, and push processing onto a queue; store MessageID/MessageUUID at send time so you can join.

Testing. Mock the wrapper, not Mailjet\Client. Assert the array you would post; use sandbox for one integration test. The SDK returns a Mailjet\Response, so success(), getStatus(), getReasonPhrase(), and getData() are your seams.

Gotchas and Tips

  • Maintenance risk is the headline. Last release 2019, 33 stars, zero dependents, no recent Symfony/PHP 8+ compatibility. Check composer.json constraints before adding it; expect conflicts with symfony/mailer and modern PHP. Forking or copying the ~4 files of DI wiring is usually cheaper than negotiating constraints.
  • Don't try to bridge a Symfony bundle into Laravel. There is no sensible adapter for bundle extensions and compiler passes. Use the SDK directly.
  • API v3 vs v3.1 payloads differ. v3.0 uses FromEmail/Recipients; v3.1 uses Messages/To/From. Which one you get depends on the Resources::EMAIL_SEND constant and the client's version setting in the installed SDK — verify in vendor rather than trusting the README. Mailjet's current guidance is v3.1.
  • Config key drift. api_key/secret_key versus public_key/private_key changed across tags (and the older mailjet/mailjetBundle lineage). Always run config:dump-reference and debug:config against the exact version you installed.
  • Private services. On Symfony 4+, $container->get('...') on the bundle's service will throw. Inject it, or add an alias to Mailjet\Client in your own services.yaml so autowiring works.
  • Check success(), not just HTTP 200. Mailjet returns structured error bodies in getData()['ErrorMessage']; log the full body. A 400 usually means a single malformed recipient or template variable, and the message text points at it.
  • Rate limits and 429s. Batch aggressively (≤50 messages/call) and retry with backoff, or a bulk send will silently degrade.
  • Attachments. Base64-encoded in the payload; large files blow up memory and request size. Send links instead, or stream from storage with strict size caps.
  • Log correlation IDs. Persist CustomID plus the returned MessageID/MessageUUID for every send. Mailjet's dashboard event log and webhooks are much harder to use without them.
  • Sandbox masks delivery problems. A sandbox 200 tells you the JSON parses, not that SPF/DKIM, sender validation, or template variables are correct. Send one real message to yourself per environment.
  • Extension points are minimal. If you need retries, circuit breaking, or a Mailer transport, build a thin service around the SDK — don't patch vendor/ and don't expect the bundle to grow features.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle