Skip to main content
A Saloon-based SDK for interacting with the Brevo (formerly Sendinblue) API v3. Brevo provides email marketing, transactional emails, SMS, and marketing automation services.

Installation

The SDK is included as part of the Inly Core package. No additional installation is required.

Configuration

Add your Brevo API key to your .env file:
BREVO_API_KEY=your-api-key-here
BREVO_BASE_URL=https://api.brevo.com/v3  # Optional, defaults to https://api.brevo.com/v3
BREVO_TIMEOUT=60  # Optional, defaults to 60 seconds
The SDK automatically loads configuration from config/brevo.php.

Getting Your API Key

  1. Log in to your Brevo account
  2. Navigate to SettingsAPI Keys
  3. Create a new API key or copy an existing one
  4. Add it to your .env file
Keep your API key secure and never commit it to version control. Always use environment variables.

Laravel Integration

Service Container Registration

For seamless Laravel integration, register Brevo as a singleton in your AppServiceProvider. The Inly Core package provides a stub file with the recommended setup:
// app/Providers/AppServiceProvider.php

use Inly\Core\Connectors\Brevo\Brevo;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Brevo SDK
        $this->app->singleton(Brevo::class, function ($app) {
            return new Brevo(
                apiKey: config('brevo.api_key')
            );
        });
    }
}
The stub file at vendor/inly/core/stubs/laravel/app/Providers/AppServiceProvider.php contains commented examples for all available SDKs. Copy the Brevo section and uncomment it in your application’s AppServiceProvider.

Dependency Injection

Once registered, you can inject Brevo into your classes:
use Inly\Core\Connectors\Brevo\Brevo;

class NewsletterController extends Controller
{
    public function __construct(
        protected Brevo $brevo
    ) {}

    public function subscribe(Request $request)
    {
        $this->brevo->contacts()->create(
            email: $request->email,
            listIds: [config('brevo.newsletter_list_id')]
        );
        
        return back()->withSuccess(__('Subscribed successfully!'));
    }
}

Basic Usage

Initialization

use Inly\Core\Connectors\Brevo\Brevo;

// Create instance - automatically loads from config
$brevo = new Brevo();

// Or create with explicit API key
$brevo = new Brevo('your-api-key');

// Or set it later
$brevo->setApiKey('your-api-key');

// Check if configured
if ($brevo->isConfigured()) {
    // Ready to use
}

// Using dependency injection (recommended)
public function __construct(protected Brevo $brevo) {}

Account Information

Get details about your Brevo account:
// Get account info
$account = $brevo->account()->get();

echo $account['email'];
echo $account['companyName'];
echo $account['plan']['type'];
echo $account['relay']['data']['userName'];
{
  "email": "user@example.com",
  "companyName": "My Company",
  "plan": {
    "type": "enterprise",
    "credits": 50000
  }
}

Contacts

Manage your contact lists and individual contacts.

List All Contacts

// Get all contacts as a Collection
$contacts = $brevo->contacts()->list();

foreach ($contacts as $contact) {
    echo $contact['email'];
    echo $contact['attributes']['FIRSTNAME'];
}

// With parameters
$contacts = $brevo->contacts()->list(
    limit: 50,
    offset: 0,
    modifiedSince: '2024-01-01'
);

Get Single Contact

// By email or ID
$contact = $brevo->contacts()->get('user@example.com');

echo $contact['email'];
echo $contact['attributes']['FIRSTNAME'];
echo $contact['attributes']['LASTNAME'];
print_r($contact['listIds']);
{
  "email": "user@example.com",
  "id": 123,
  "emailBlacklisted": false,
  "smsBlacklisted": false,
  "attributes": {
    "FIRSTNAME": "John",
    "LASTNAME": "Doe",
    "SMS": "+1234567890"
  },
  "listIds": [1, 2, 3],
  "statistics": {
    "clicked": 5,
    "opened": 10
  }
}

Create Contact

// Create a new contact
$result = $brevo->contacts()->create(
    email: 'new@example.com',
    attributes: [
        'FIRSTNAME' => 'John',
        'LASTNAME' => 'Doe',
        'SMS' => '+1234567890'
    ],
    listIds: [1, 2],
    emailBlacklisted: false,
    smsBlacklisted: false
);

echo $result['id']; // New contact ID
Contact attributes must be pre-defined in your Brevo account. Go to ContactsSettingsContact Attributes to manage them.

Update Contact

// Update existing contact
$brevo->contacts()->update(
    identifier: 'user@example.com',
    attributes: [
        'FIRSTNAME' => 'Jane',
        'COMPANY' => 'Acme Corp'
    ],
    listIds: [3, 4], // Replace list memberships
    unlinkListIds: [1, 2] // Remove from these lists
);

Delete Contact

// Delete a contact permanently
$brevo->contacts()->delete('user@example.com');
Deleting a contact is permanent and cannot be undone. Consider unsubscribing them from lists instead.

Manual Pagination

// For large datasets, use manual pagination
$paginator = $brevo->contacts()->paginate();

foreach ($paginator as $response) {
    $contacts = $response->json('contacts', []);
    
    foreach ($contacts as $contact) {
        // Process each contact
        echo $contact['email'];
    }
}

Lists

Manage contact lists (segments) in your Brevo account.

List All Lists

// Get all contact lists
$lists = $brevo->lists()->list();

foreach ($lists as $list) {
    echo $list['name'];
    echo $list['totalSubscribers'];
}

Get Single List

// Get specific list details
$list = $brevo->lists()->get(123);

echo $list['name'];
echo $list['totalSubscribers'];
echo $list['folderId'];
{
  "id": 123,
  "name": "Newsletter Subscribers",
  "totalSubscribers": 1500,
  "totalBlacklisted": 10,
  "folderId": 1,
  "createdAt": "2024-01-01T00:00:00.000Z",
  "dynamicList": false
}

Create List

// Create a new contact list
$result = $brevo->lists()->create(
    name: 'My New List',
    folderId: 1
);

echo $result['id']; // New list ID

Update List

// Update list details
$brevo->lists()->update(
    listId: 123,
    name: 'Updated List Name',
    folderId: 2
);

Delete List

// Delete a list and all its contacts
$brevo->lists()->delete(123);
Deleting a list will remove all contacts from that list. The contacts themselves will remain in your account unless they’re not in any other lists.

Manual Pagination

// Paginate through lists
$paginator = $brevo->lists()->paginate();

foreach ($paginator as $response) {
    $lists = $response->json('lists', []);
    // Process lists...
}

Transactional Emails

Send transactional emails and track their delivery.

Send Email

// Send a transactional email with HTML content
$result = $brevo->transactionalEmails()->send(
    to: [
        ['email' => 'recipient@example.com', 'name' => 'John Doe']
    ],
    subject: 'Welcome to Our Service',
    htmlContent: '<h1>Hello!</h1><p>Welcome to our service.</p>',
    sender: [
        'email' => 'sender@example.com',
        'name' => 'My Company'
    ],
    replyTo: [
        'email' => 'reply@example.com',
        'name' => 'Support Team'
    ]
);

echo $result['messageId']; // Track the email
The sender email must be verified in your Brevo account before sending emails.

Send with Template

// Send using a pre-defined template
$result = $brevo->transactionalEmails()->sendWithTemplate(
    templateId: 1,
    to: [
        ['email' => 'recipient@example.com', 'name' => 'John Doe']
    ],
    params: [
        'FIRSTNAME' => 'John',
        'ORDER_ID' => '12345',
        'TOTAL_AMOUNT' => '$99.99'
    ]
);

echo $result['messageId'];
{
  "messageId": "<202401011200.1234567890@smtp-relay.brevo.com>"
}

Advanced Send Options

// Send with attachments, CC, BCC, and more
$result = $brevo->transactionalEmails()->send(
    to: [['email' => 'recipient@example.com', 'name' => 'John Doe']],
    subject: 'Invoice #12345',
    htmlContent: '<h1>Your Invoice</h1>',
    sender: ['email' => 'billing@example.com', 'name' => 'Billing'],
    cc: [['email' => 'manager@example.com']],
    bcc: [['email' => 'archive@example.com']],
    attachment: [
        [
            'name' => 'invoice.pdf',
            'content' => base64_encode($pdfContent)
        ]
    ],
    headers: [
        'X-Custom-Header' => 'custom-value'
    ],
    tags: ['invoice', 'billing']
);

Track Email Events

// Get email events/activity
$events = $brevo->transactionalEmails()->events(
    email: 'user@example.com',
    event: 'delivered', // 'delivered', 'opened', 'clicked', 'bounced', 'spam', 'blocked'
    startDate: '2024-01-01',
    endDate: '2024-12-31',
    limit: 100
);

foreach ($events as $event) {
    echo $event['event']; // 'delivered', 'opened', etc.
    echo $event['date'];
    echo $event['subject'];
}
{
  "events": [
    {
      "email": "user@example.com",
      "event": "delivered",
      "subject": "Welcome Email",
      "messageId": "<202401011200.1234567890@smtp-relay.brevo.com>",
      "date": "2024-01-01T12:00:00.000Z",
      "tags": ["welcome"]
    }
  ]
}

Manual Event Pagination

// For large event datasets
$paginator = $brevo->transactionalEmails()->paginateEvents(
    email: 'user@example.com',
    event: 'opened'
);

foreach ($paginator as $response) {
    $events = $response->json('events', []);
    // Process events...
}

Senders

Manage verified sender email addresses and domains.

List Senders

// Get all verified senders
$senders = $brevo->senders()->list();

foreach ($senders as $sender) {
    echo $sender['email'];
    echo $sender['name'];
    echo $sender['active'] ? 'Active' : 'Inactive';
}
{
  "senders": [
    {
      "id": 1,
      "name": "My Company",
      "email": "noreply@mycompany.com",
      "active": true,
      "ips": [
        {
          "ip": "123.45.67.89",
          "domain": "mycompany.com"
        }
      ]
    }
  ]
}

Create Sender

// Create a new sender
$result = $brevo->senders()->create(
    name: 'My Company',
    email: 'noreply@mycompany.com'
);

echo $result['id']; // New sender ID
After creating a sender, you must verify the email address or domain before you can send emails from it. Check your email for a verification link.

Error Handling

The SDK automatically throws exceptions for API errors. Always wrap your calls in try-catch blocks:
use Saloon\Exceptions\Request\RequestException;
use Exception;

try {
    $contact = $brevo->contacts()->get('nonexistent@example.com');
} catch (RequestException $e) {
    // Handle API errors (4xx, 5xx)
    $statusCode = $e->getResponse()->status();
    $errorMessage = $e->getResponse()->json('message');
    
    if ($statusCode === 404) {
        // Contact not found
        echo "Contact does not exist";
    } else {
        echo "API Error: {$errorMessage}";
    }
} catch (Exception $e) {
    // Handle other errors
    echo "Error: {$e->getMessage()}";
}

Rate Limiting

Brevo enforces rate limits based on your plan:
PlanRequests per Second
Free10 requests/sec
Starter10 requests/sec
Business100 requests/sec
EnterpriseCustom
The SDK automatically handles rate limit errors. If you exceed limits, you’ll receive a 429 Too Many Requests exception.

Testing

Test your SDK configuration with the included command:
php artisan test:brevo
This will:
  • ✅ Verify your API key is configured
  • ✅ Test connectivity to Brevo API
  • ✅ Display account information
  • ✅ Show sample contact data

Available Resources

ResourceMethodsDescription
account()get()Get account information
contacts()list(), get(), create(), update(), delete(), paginate()Manage contacts
lists()list(), get(), create(), update(), delete(), paginate()Manage contact lists
transactionalEmails()send(), sendWithTemplate(), events(), paginateEvents()Send and track emails
senders()list(), create()Manage sender addresses

Common Use Cases

Newsletter Signup Flow

use Inly\Core\Connectors\Brevo\Brevo;
use Illuminate\Http\Request;

class NewsletterController extends Controller
{
    public function __construct(
        protected Brevo $brevo
    ) {}

    public function subscribe(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'first_name' => 'required|string',
            'last_name' => 'required|string',
        ]);

        // 1. Create a contact
        $this->brevo->contacts()->create(
            email: $request->email,
            attributes: [
                'FIRSTNAME' => $request->first_name,
                'LASTNAME' => $request->last_name
            ],
            listIds: [config('brevo.newsletter_list_id')]
        );

        // 2. Send welcome email
        $this->brevo->transactionalEmails()->sendWithTemplate(
            templateId: config('brevo.welcome_template_id'),
            to: [['email' => $request->email, 'name' => $request->first_name]],
            params: ['FIRSTNAME' => $request->first_name]
        );

        return back()->withSuccess(__('Subscribed successfully!'));
    }
}

Order Confirmation Email

use Inly\Core\Connectors\Brevo\Brevo;

class OrderService
{
    public function __construct(
        protected Brevo $brevo
    ) {}

    public function sendConfirmation(Order $order): void
    {
        // Send order confirmation with invoice
        $this->brevo->transactionalEmails()->send(
            to: [['email' => $order->customer->email, 'name' => $order->customer->name]],
            subject: "Order Confirmation #{$order->id}",
            htmlContent: view('emails.order-confirmation', compact('order'))->render(),
            sender: ['email' => 'orders@myshop.com', 'name' => 'My Shop'],
            attachment: [
                [
                    'name' => "invoice-{$order->id}.pdf",
                    'content' => base64_encode($order->generateInvoicePdf())
                ]
            ],
            tags: ['order-confirmation', "order-{$order->id}"]
        );
    }
}

Sync Users to Marketing List

use Inly\Core\Connectors\Brevo\Brevo;
use Illuminate\Support\Facades\Log;
use Saloon\Exceptions\Request\RequestException;

class SyncUsersToBrevoJob
{
    public function __construct(
        protected Brevo $brevo
    ) {}

    public function handle(): void
    {
        // Sync active users to a marketing list
        $users = User::whereActive(true)->get();

        foreach ($users->chunk(100) as $chunk) {
            foreach ($chunk as $user) {
                try {
                    $this->brevo->contacts()->create(
                        email: $user->email,
                        attributes: [
                            'FIRSTNAME' => $user->first_name,
                            'LASTNAME' => $user->last_name,
                            'SIGNUP_DATE' => $user->created_at->format('Y-m-d')
                        ],
                        listIds: [config('brevo.active_users_list_id')],
                        updateEnabled: true // Update if exists
                    );
                } catch (RequestException $e) {
                    Log::warning("Failed to sync user {$user->id}: {$e->getMessage()}");
                }
            }
            
            // Rate limiting: wait between chunks
            sleep(1);
        }
    }
}

Additional Resources

Support

For issues or questions:
  • Check the Brevo API Status
  • Contact Brevo Support through your dashboard
  • Report SDK bugs to the Inly Core team