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

Sendinblue Laravel Package

splash/sendinblue

A Laravel package for integrating Sendinblue (now Brevo) into your applications. Send transactional emails and SMS, manage contacts, and access common API operations through a simple, fluent wrapper with streamlined configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

The splash/sendinblue bundle is an embedded connector for the Splash Sync framework — it is not usable standalone. It plugs a Brevo (formerly SendInBlue) account into a Splash Sync node so contacts, lists and related marketing objects can be pushed/pulled against a source system (PrestaShop, Magento, Akeneo, custom Symfony app, etc.).

Prerequisites:

  • A working Splash Sync installation (splash/splash-bundle, splash/phpcore, splash/php-bundle) already configured for a source system.
  • A Brevo API key (v3 key, not the legacy v2 key) with the marketing permissions you need.
  • PHP 8.1+ / Symfony 5.4+ / 6.x (check composer.json in the repo — the constraint has moved over time and the repo has effectively zero recent activity, so verify against your Symfony version before installing).

First steps:

  1. composer require splash/sendinblue (you’ll likely have to use --dev or pin a specific tag; there is no stable release stream to lean on).
  2. Register the bundle in config/bundles.php:
    Splash\Bundle\BrevoBundle\SplashBrevoBundle::class => ['all' => true],
    
  3. Import the bundle’s service config if it isn't auto-loaded (check Resources/config/ in the repo — typical Splash bundles register their Services/* classes and a Model/* mapping through services.yaml).
  4. Add the API key. Splash connectors usually read credentials from the server configuration of the current Splash node, not from your app’s env. In a typical Splash setup you register the connector in the Splash back-office (or via the splash.php config on the node) and paste the Brevo v3 key there.
  5. Look first at src/Services/ (the API wrapper: contacts, lists, ping, rate-limit handling) and src/Models/ (the Splash model classes such as ThirdParty, Address, etc.). Those two folders tell you what the connector actually supports.

First use case: syncing Contacts — the natural lowest-risk flow. Once the key is set, run Splash’s Ping / SelfTest actions for the connector in the back-office. A green ping tells you the key works and the connector is reachable; then push a single test contact into a Brevo list and confirm it appears before wiring up the full object mapping.

Implementation Patterns

Model-driven sync. Splash connectors are structured around Splash Models (the abstract objects exposed to the framework: ThirdParty, Address, Product, Order, etc.). Each model implements get/set/delete and declares field mappings. To extend behavior you generally subclass or override the service that talks to Brevo, not the framework. Search src/Services/ for the class that issues /v3/contacts calls — that is your extension point.

Service-layer wrapper. Brevo’s v3 API is REST/JSON with api-key header auth. The bundle’s service classes usually wrap Guzzle and expose typed methods like getContactByEmail, createOrUpdateContact, addContactToList, getLists. Call these from your own code when you need Brevo access outside of a Splash object — e.g. for one-off backfills. Reuse the bundle’s client rather than instantiating your own, so you inherit its error handling and base URL.

Field mapping / attribute handling. Brevo contacts have fixed attributes (EMAIL, FIRSTNAME, LASTNAME, SMS) plus custom attributes you define in Brevo. In Splash terms these are the model fields. When adding a new field:

  • Define it in Brevo first (Contacts → Settings → Contact attributes).
  • Add it to the appropriate Splash model field list (or override it in your app).
  • Confirm the type: Brevo v3 will silently reject or coerce wrong types (e.g. sending a date object where it wants YYYY-MM-DD).

Webhook integration. Splash supports inbound webhooks so the connector can react to Brevo events (contact created, unsubscribed, etc.). If you enable them, register the Splash webhook URL in Brevo and expose a public, TLS-terminated endpoint. Treat this as optional — most setups are pull-only.

Sync workflow. Typical loop:

  1. Source record changes in your app (event/listener).
  2. Splash marks the corresponding model as dirty.
  3. The connector’s scheduled/queued sync calls the Brevo service.
  4. On 200/201 the local hash is updated so the same change isn’t re-sent.
  5. On 4xx (validation, duplicate, attribute missing) Splash logs it — surface these in the Splash log view, not var/log.

Backfilling. For a one-time import, drive the sync by enqueuing the same models you’d sync normally — do not call Brevo directly from a script, or you’ll drift from the connector’s dedup hashes and cause duplicate sends later.

Gotchas and Tips

  • Maintenance risk. Zero stars and zero dependents is the headline. Treat this as a read-only reference implementation: pin a commit or tag in composer.json, and budget time to fork if you depend on it in production. There is no upgrade path to assume.
  • v2 vs v3 API. SendInBlue v2 endpoints are long gone. Anything in the repo that still references api.sendinblue.com/v2 or X-Mailin-Token is dead code; the v3 host is api.brevo.com with an api-key header.
  • Rate limits. Brevo v3 enforces tight per-minute quotas (contact writes especially). The connector is unlikely to include a token-bucket; if you sync in bulk, throttle upstream (Splash queues or your own worker) or you’ll see 429s that surface as opaque sync failures.
  • EMAIL is the primary key for contacts. Changing a contact’s email creates a new contact unless you use the ext_id (external ID) field. Map your stable local ID to Brevo’s ext_id early — it saves you a painful migration later.
  • List membership is not a contact attribute. Adding to a list is a separate API call and a separate Splash field/action. Sync contacts and list memberships as distinct concerns.
  • Attribute type mismatches are silent. Brevo accepts a payload and drops fields whose type doesn’t match the attribute definition (e.g. a boolean where it expects "true"/"false"). Debug by inspecting the raw request/response in the Splash transport log first, before touching the model.
  • Ping is your smoke test. In Splash, the Ping (self-test) action for a connector validates credentials and connectivity. Use it after every key change and after any composer update; if ping fails, nothing else will work.
  • Config lives on the node, not in .env. The Brevo key is a Splash server-level setting. Do not expect BREVO_API_KEY in .env to do anything; check splash node settings / Splash back-office first.
  • Symfony service autowiring edge cases. Old Splash bundles frequently declare services with explicit IDs and no autowire, so private + constructor injection from your app code needs an alias or a public: true override in your own services.yaml.
  • Extension point — override the service. To customize behavior safely (e.g. add a custom attribute on every contact sync), decorate the bundle’s contact service rather than forking:
    App\Brevo\ContactService:
        decorates: 'splash.sendinblue.service.contact'
        arguments: ['@App\Brevo\ContactService.inner']
    
    (Replace the decorated ID with the actual one from the bundle’s services.yaml — it varies by version.)
  • Testing. There is no test suite to rely on. Write your own contract tests against a Brevo sandbox account: ping, create contact, add to list, update contact, delete contact. This is the single highest-value thing you can do before shipping.
  • Deletion semantics differ. Splash delete on a contact may just mark it blacklisted in Brevo. Check the implementation before assuming a hard delete, or you’ll leave stale records.
  • Logs. Use Splash’s dedicated log channel (splash logger, and the back-office log viewer) rather than monolog’s default stack — the connector typically logs there, and the framework log viewer parses it into request/response pairs, which is far easier than digging through JSON strings.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource