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

Mailin Api Php Laravel Package

mailin-api/mailin-api-php

PHP client for Brevo's (formerly Sendinblue) transactional email and SMS API. Send messages, manage contacts and lists, and track events with a lightweight wrapper that drops easily into Laravel or any PHP project.

Deep Wiki
Context7

Getting Started

This is the official Sendinblue (formerly Mailin) v2.0 API wrapper — a single, unnamespaced PHP class that speaks to https://api.sendinblue.com/v2.0. It was last released in 2017 and the repo is archived, so treat it as a legacy integration: pin the version, wrap it, and plan an exit to the Brevo v3 API.

Minimal setup:

composer require mailin-api/mailin-api-php

The package predates PSR-4. If Composer does not register the global Mailin class for you, add it to your root composer.json and composer dump-autoload:

"autoload": { "files": ["vendor/mailin-api/mailin-api-php/Mailin.php"] }

Pull the API key from the Sendinblue/Brevo dashboard (SMTP & API → API Keys), store it in .env, and expose it via config/services.php:

// config/services.php
'mailin' => [
    'url' => env('MAILIN_URL', 'https://api.sendinblue.com/v2.0'),
    'key' => env('MAILIN_API_KEY'),
],

First use case — a transactional welcome email on registration:

$mailin = new Mailin(config('services.mailin.url'), config('services.mailin.key'));

$result = $mailin->send_email([
    'to'      => ['[email protected]' => 'Jane Doe'],
    'from'    => ['[email protected]', 'Your App'],
    'subject' => 'Welcome aboard',
    'html'    => view('emails.welcome', ['user' => $user])->render(),
]);

if (($result['code'] ?? null) !== 'success') {
    Log::error('Mailin send failed', ['response' => $result]);
}

Where to look first: the Mailin.php class itself. Every public method (send_email, send_sms, create_list, get_account, get_campaigns_v2, …) maps 1:1 to a v2 endpoint and takes a single associative array. The README examples are the only documentation you get — there is no generated SDK reference.

Implementation Patterns

Bind it once, inject it everywhere. Don't new Mailin(...) at call sites. Register a singleton in a service provider and type-hint the wrapper, not the SDK:

// app/Services/MailinService.php
class MailinService
{
    public function __construct(private \Mailin $client) {}

    public function sendTransactional(array $payload): array
    {
        $response = $this->client->send_email($payload);

        if (($response['code'] ?? null) !== 'success') {
            throw new MailinException($response['message'] ?? 'Unknown Mailin error', $response);
        }

        return $response['data'] ?? [];
    }
}
// AppServiceProvider::register()
$this->app->singleton(\Mailin::class, fn () => new \Mailin(
    config('services.mailin.url'),
    config('services.mailin.key'),
));

Queue everything. The SDK is synchronous cURL with no timeout/retry configuration. A slow Sendinblue response becomes a slow HTTP request in your app. Wrap sends in a queued job (ShouldQueue) and let Laravel's retry/backoff handle transient failures. This is the single biggest day-to-day win.

Build a thin Mailable/Notification bridge. You can't drop this into Laravel's Mail transport without writing a custom Transport implementation; the path of least resistance is a dedicated NotificationChannel or a MailinService::sendTemplate() helper, then call that from notifications and jobs. This keeps the rest of the codebase free of the SDK's array shapes.

Test by binding a fake. Because you injected the wrapper, swap it in tests with a spy that records payloads. Never assert against the real client in feature tests.

Multi-purpose account operations. Beyond send_email, developers commonly use send_sms, create_list/add_to_list for contact syncing, and get_account for health checks on a scheduled command. Each takes a flat associative array; keep payload builders in small helper methods so key typos surface in tests rather than at runtime.

Integration tip: if you only need transactional email, prefer a Laravel-native transport (SMTP or a maintained Brevo/Sendinblue package). Reach for this SDK when you need the v2-specific endpoints (SMS, legacy list/campaign management) that your account still relies on.

Gotchas and Tips

  • Archived and on a dead API surface. This targets Sendinblue API v2.0, which has been superseded by v3 (Brevo). Verify the endpoint still answers for your account before building on it; new work should target the v3 SDK or raw HTTP.
  • No namespaces. The class is a global Mailin in the root namespace. It will collide with anything else declaring Mailin and can't be autoloaded under PSR-4. Namespacing it (a one-line fork) is often the first thing teams do.
  • No exceptions on API errors. The client returns a decoded array; failures appear as ['code' => 'failure', 'message' => '…'], not exceptions. Always check the code key and throw your own exception, or errors vanish silently into logs you never wrote.
  • Transport-level failures are quieter. cURL/DNS/timeout errors can come back as empty strings or false rather than a structured response. Defensive ?? null checks and null-safe decoding are worth it.
  • No timeouts or retries. Configure PHP's default_socket_timeout and cURL defaults at the app level; rely on queued job retries rather than the SDK.
  • Exact array keys. Payloads are to, from, subject, html, text, cc, bcc, attachment. Keys are not validated; a typo yields a generic failure. Builders + tests are your safety net.
  • Attachments are base64. Pass content (not just a path) with a filename and MIME type; don't hand the SDK a filesystem path and expect it to read the file.
  • Sender reputation is on you. Verify the sending domain, set SPF/DKIM, and keep the from address on a verified domain — otherwise the API rejects or deliverability tanks regardless of the code.
  • Secrets. The API key is passed to the constructor as a plain string; keep it in .env, never in config defaults or logs.
  • Extension points are essentially nil. There are no hooks, events, or middleware. Any behavior you need beyond the raw calls belongs in your wrapper around the class.
  • PHP 8 compatibility is unverified. The code is from the PHP 5.x/7.x era; it generally runs on 8.x, but smoke-test before upgrading.
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.
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
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
cgv/localized-resource