splash/mailjet
A Laravel package that adds Mailjet mail transport support, letting applications send email through the Mailjet API using Laravel's native mailer. Includes service provider wiring and configuration for quick setup.
splash/mailjet is not a Mailjet SDK wrapper you reach for when you want to send transactional email. It is a SplashSync connector bundle: a thin, opinionated adapter that maps Splash objects (ThirdParties, Addresses, etc.) onto Mailjet contacts and lists, and is designed to be embedded inside the SplashSync server rather than bootstrapped in a normal Laravel app. Treat it as infrastructure for a Splash deployment, not a general-purpose library.
Minimal steps:
splash/php-core (or the Splash framework packages) to already be present and will pull its own mailjet/apiv3-style client. Do not try to composer require it into a bare Laravel skeleton and expect service providers to resolve.config/bundles.php when running under a Symfony-flavoured Splash host). The bundle class lives at the package root under Splash\Bundle\MailjetBundle.Form/ConnectorSettingsType or similar) from the Splash back-office, and paste your Mailjet API Key and API Secret. These are stored by Splash's ConfigurationService, not in .env — a common source of confusion.Resources/config/services.yaml (to see which services are wired) → the Services/ directory (the actual object mapping) → Form/ for the credential fields.Service-per-object mapping. Splash connectors implement a fixed set of interfaces per object type — CrudServiceInterface, PrimaryServiceInterface, ListServiceInterface, ObjectServiceInterface. Each Mailjet resource you want to expose gets its own service class wired in services.yaml and tagged so Splash's service locator can find it. Adding a new object type is a matter of copying an existing service, changing the getType()/getObjectClass() methods, and tagging it.
The commit lifecycle is the workflow. You never call this package directly from a controller. Splash's sync engine invokes your service's create(), update(), delete() and commit() methods in response to upstream changes. commit() is where the actual Mailjet HTTP call happens — the create/update methods only populate an in-memory object. Keep them side-effect free; that separation is what makes Splash retries safe.
Settings, not config files. Connector parameters (API keys, default list ID, sandbox flag) are read via the injected configuration service at call time:
$apiKey = $this->configuration->getParameter('MAILJET_APIKEY');
$listId = $this->configuration->getParameter('MAILJET_LIST');
Because these are resolved per-request rather than baked at container compile time, you can point a single Splash instance at different Mailjet accounts per connector configuration — useful for multi-tenant or staging/prod splits.
Integration tip: Mailjet contacts are keyed by email, and Splash's ThirdParty primary key is usually an internal ID. Implement getPrimaryKey() in terms of the email field and let a separate AddressService handle the Properties payload. Trying to use the internal ID as the Mailjet contact ID will cause duplicate contacts on the next sync.
Testing. Use Splash's own test toolkit rather than raw PHPUnit against the Mailjet client; the connector services assume an initialized Splash context. Mock at the HTTP client boundary and assert on the outbound payload shape.
extra.laravel.providers. If you are trying to use this in a plain Laravel app, you are on the wrong package — you want a Mailjet API client plus your own sync logic.composer.json constraints on splash/php-core move fast. Lock the Connector and Core versions together and expect to bump both simultaneously./contact and /contactdata writes. Splash will happily queue hundreds of commits; if your services fire one HTTP call per commit, a bulk import will 429. Batch inside commit() where the object type allows it, and log throttled responses rather than throwing — Splash retries on exception and will amplify the problem.Properties to an undeclared Mailjet contact property returns a 400 that surfaces as a generic Splash commit error. Create the MailjetContactProperty definitions first (or add them to your connector's install/verify step) and map names exactly — Mailjet is case-sensitive on property names.SyncException message. If you see nothing at all, the service tag is missing from services.yaml, not a credential problem.services.yaml (same service ID, your class) rather than forking the bundle. Forking is an option — the bundle is small — but you will lose every upstream fix, and given the near-zero activity you should assume there will be very few, so a local fork is a defensible choice here.sandbox/test connector parameter exists, verify it actually routes to Mailjet's sandbox endpoint. Broken sandbox toggles are common in low-activity connectors, and the failure mode is silently mutating production contacts.How can I help you explore Laravel packages today?