PHP SDK

Learn how to integrate the Brevo API into your PHP applications.

Overview

The Brevo PHP SDK (getbrevo/brevo-php) is a type-safe client library for the Brevo API. It provides:

  • A unified Brevo client with namespaced service clients
  • Strongly typed request and response objects with full PHPDoc annotations
  • PSR-18 HTTP client compatibility (Guzzle, Symfony HttpClient, etc.)
  • Automatic retries with exponential backoff
  • Structured error handling via BrevoApiException

Packagist

Version 4.0 is a full rewrite and is not backwards compatible with the legacy SDK. The legacy SDK will continue to receive critical security updates but no new features. We recommend migrating to v4.x for new and existing projects.

Requirements

  • PHP 8.1+
  • ext-json
  • A PSR-18 HTTP client (e.g., Guzzle, Symfony HttpClient)

Installation

Install the SDK using Composer:

$composer require getbrevo/brevo-php

Guzzle is recommended as the HTTP client:

$composer require getbrevo/brevo-php guzzlehttp/guzzle

If no HTTP client is provided, the SDK uses php-http/discovery to auto-detect an installed PSR-18 client.

Quick start

Initialize the client and send your first email:

quick_start.php
1<?php
2
3require_once __DIR__ . '/vendor/autoload.php';
4
5use Brevo\Brevo;
6use Brevo\TransactionalEmails\Requests\SendTransacEmailRequest;
7use Brevo\TransactionalEmails\Types\SendTransacEmailRequestSender;
8use Brevo\TransactionalEmails\Types\SendTransacEmailRequestToItem;
9
10$client = new Brevo(apiKey: 'your-api-key');
11
12$result = $client->transactionalEmails->sendTransacEmail(
13 new SendTransacEmailRequest([
14 'subject' => 'Hello from Brevo!',
15 'htmlContent' => '<html><body><p>Hello,</p><p>This is my first transactional email.</p></body></html>',
16 'sender' => new SendTransacEmailRequestSender([
17 'name' => 'Alex from Brevo',
18 'email' => 'hello@brevo.com',
19 ]),
20 'to' => [
21 new SendTransacEmailRequestToItem([
22 'email' => 'johndoe@example.com',
23 'name' => 'John Doe',
24 ]),
25 ],
26 ])
27);
28
29echo 'Email sent. Message ID: ' . $result->messageId . PHP_EOL;

Configuration

Pass an options array as the second argument to configure the client:

configuration.php
1$client = new Brevo('your-api-key', [
2 'timeout' => 30, // seconds
3 'maxRetries' => 3,
4]);

Constructor parameters

ParameterTypeDefaultDescription
apiKeystringRequiredYour Brevo API key
timeoutfloatnullRequest timeout in seconds. Defaults to the underlying HTTP client’s default.
baseUrlstringnullOverride the default API base URL
maxRetriesint2Maximum retry attempts on retryable errors
clientClientInterfacenullCustom PSR-18 HTTP client
headersarray<string, string>nullAdditional default headers sent with every request

Error handling

BrevoApiException is thrown for any non-2xx HTTP response. Catch it to inspect the status code and response body:

error_handling.php
1use Brevo\Exceptions\BrevoApiException;
2use Brevo\Exceptions\BrevoException;
3
4try {
5 $client->transactionalEmails->sendTransacEmail($request);
6} catch (BrevoApiException $e) {
7 $statusCode = $e->getCode();
8 $body = $e->getBody();
9
10 if ($statusCode === 401) {
11 echo 'Invalid API key';
12 } elseif ($statusCode === 429) {
13 echo 'Rate limited. Check Retry-After header.';
14 } else {
15 echo "API error {$statusCode}: " . $e->getMessage();
16 }
17} catch (BrevoException $e) {
18 echo 'SDK error: ' . $e->getMessage();
19}

Exception classes

ClassDescription
BrevoApiExceptionThrown for non-2xx HTTP responses
BrevoExceptionBase class for all SDK-level errors

BrevoApiException exposes:

  • getCode() — HTTP status code
  • getMessage() — Error message
  • getBody() — Parsed response body

Status codes

CodeMeaning
400Bad Request
401Unauthorized
403Forbidden
404Not Found
422Unprocessable Entity
429Too Many Requests
5xxServer Error

Retries

Automatic retries with exponential backoff are enabled by default (2 retries). Configure at the client or request level:

retries.php
1// Client-level
2$client = new Brevo('your-api-key', [
3 'maxRetries' => 3,
4]);
5
6// Request-level (overrides client setting)
7$client->transactionalEmails->sendTransacEmail($request, [
8 'maxRetries' => 0, // Disable retries for this request
9]);

Retry behavior

  • Retryable status codes: 408, 429, 5xx
  • Backoff schedule: ~1s, ~2s, ~4s (exponential, base 1000ms) with ±10% symmetric jitter
  • Maximum delay: 60s per retry interval
  • Rate limit headers: Respects Retry-After and X-RateLimit-Reset response headers

Timeouts

No default timeout is configured. Unless you set one, the underlying HTTP client’s default applies (Guzzle defaults to no timeout). Set an explicit timeout at the client or request level:

timeouts.php
1// Client-level
2$client = new Brevo('your-api-key', [
3 'timeout' => 30,
4]);
5
6// Request-level (overrides client setting)
7$client->transactionalEmails->sendTransacEmail($request, [
8 'timeout' => 10,
9]);

Timeout forwarding is supported for Guzzle and Symfony HttpClient. For other PSR-18 clients, the timeout value is ignored and a PHP warning is triggered.

Use caseTimeout
Standard API calls30–60s
Quick operations10–15s
Bulk operations120–300s
Real-time / low-latency5–10s

Request options

Both timeout, maxRetries, and headers can be overridden per request by passing an options array as the last argument:

request_options.php
1$client->transactionalEmails->sendTransacEmail($request, [
2 'timeout' => 10,
3 'maxRetries' => 1,
4 'headers' => [
5 'X-Custom-Header' => 'custom-value',
6 ],
7]);

Query parameters

Pass query parameters via the typed request object:

query_params.php
1use Brevo\Contacts\Requests\GetContactsRequest;
2
3$client->contacts->getContacts(new GetContactsRequest([
4 'limit' => 50,
5 'offset' => 0,
6]));

Binary responses

Some endpoints (e.g., attachment downloads) return binary content directly:

binary_response.php
1$content = $client->inboundParsing->getInboundEmailAttachment($downloadToken);
2
3file_put_contents('path/to/file', $content);

Type safety

All request and response objects are strongly typed. Use the generated request classes for IDE autocomplete and static analysis:

type_safety.php
1use Brevo\TransactionalEmails\Requests\SendTransacEmailRequest;
2use Brevo\TransactionalEmails\Types\SendTransacEmailRequestSender;
3use Brevo\TransactionalEmails\Types\SendTransacEmailRequestToItem;
4
5$request = new SendTransacEmailRequest([
6 'subject' => 'First email',
7 'textContent' => 'Hello world!',
8 'sender' => new SendTransacEmailRequestSender([
9 'name' => 'Bob Wilson',
10 'email' => 'bob.wilson@brevo.com',
11 ]),
12 'to' => [
13 new SendTransacEmailRequestToItem([
14 'email' => 'sarah.davis@example.com',
15 'name' => 'Sarah Davis',
16 ]),
17 ],
18]);

Custom HTTP client

Pass any PSR-18-compatible client via the client option:

custom_http_client.php
1use Brevo\Brevo;
2use GuzzleHttp\Client;
3
4$client = new Brevo('your-api-key', [
5 'client' => new Client(['timeout' => 5.0]),
6]);

Common integrations

1use GuzzleHttp\Client;
2
3$client = new Brevo('your-api-key', [
4 'client' => new Client(['timeout' => 5.0]),
5]);
1use Symfony\Component\HttpClient\Psr18Client;
2use Symfony\Component\HttpClient\HttpClient;
3
4$client = new Brevo('your-api-key', [
5 'client' => new Psr18Client(
6 HttpClient::create(['timeout' => 5.0])
7 ),
8]);

Register the client as a singleton in a service provider:

1// AppServiceProvider.php
2use Brevo\Brevo;
3
4public function register(): void
5{
6 $this->app->singleton(Brevo::class, function () {
7 return new Brevo(apiKey: config('services.brevo.api_key'));
8 });
9}

PHP-specific considerations

API key from environment

Avoid hardcoding API keys. Use environment variables:

env_api_key.php
1$client = new Brevo(apiKey: $_ENV['BREVO_API_KEY'] ?? getenv('BREVO_API_KEY'));

In Laravel, use config('services.brevo.api_key'). In Symfony, use $_ENV['BREVO_API_KEY'] or service parameters.

Memory limits

For large operations (bulk exports, large attachments), adjust PHP’s memory_limit:

1ini_set('memory_limit', '256M');

Available services

The unified Brevo client exposes the following service namespaces:

PropertyDescription
transactionalEmailsSend emails, manage templates, blocked contacts and domains
transactionalSmsSend SMS messages and view delivery statistics
transactionalWhatsAppSend WhatsApp messages and view event reports
smsTemplatesManage SMS templates
contactsManage contacts, lists, folders, attributes and segments
emailCampaignsCreate and manage email marketing campaigns
smsCampaignsCreate and manage SMS marketing campaigns
whatsAppCampaignsCreate and manage WhatsApp campaigns and templates
companiesManage CRM companies
dealsManage CRM deals and pipelines
tasksManage CRM tasks
notesManage CRM notes
filesUpload and manage CRM files
conversationsManage conversation messages and automated messages
ecommerceManage products, categories, orders and attribution
couponsManage coupon collections and coupons
paymentsCreate and manage payment requests
eventTrack custom events
webhooksManage webhooks
sendersManage senders and IPs
domainsManage and authenticate domains
accountRetrieve account information and activity logs
inboundParsingRetrieve inbound email events and attachments
customObjectsManage custom object records
externalFeedsManage external RSS feeds
masterAccountManage sub-accounts and groups (enterprise)
userManage users and permissions
processRetrieve background process status
programManage loyalty programs
balanceManage loyalty balances and transactions
rewardManage loyalty rewards and vouchers
tierManage loyalty tiers and tier groups

Migration from the legacy SDK

Key changes

AreaLegacy SDKv4.x
Importuse Brevo\Client\Api\*use Brevo\Brevo
Client initnew TransactionalEmailsApi($httpClient, $config)new Brevo(apiKey: 'api-key')
ConfigConfiguration::getDefaultConfiguration()Constructor options array
RequestsSetter methods (->setSubject(...))Typed request objects
ErrorsGuzzle exceptionsBrevoApiException with getCode(), getBody()
HTTP clientHard Guzzle dependencyPSR-18 (any compatible client)
RetriesNot built-inAutomatic with exponential backoff
PHP7.x+8.1+

Migration example

1// Legacy SDK
2use Brevo\Client\Configuration;
3use Brevo\Client\Api\TransactionalEmailsApi;
4use Brevo\Client\Model\SendSmtpEmail;
5
6$config = Configuration::getDefaultConfiguration()
7 ->setApiKey('api-key', 'xkeysib-xxx');
8
9$api = new TransactionalEmailsApi(new \GuzzleHttp\Client(), $config);
10
11$message = new SendSmtpEmail();
12$message->setSubject('First email');
13$message->setTextContent('Hello world!');
14$message->setSender(['name' => 'Bob Wilson', 'email' => 'bob.wilson@brevo.com']);
15$message->setTo([['email' => 'sarah.davis@example.com', 'name' => 'Sarah Davis']]);
16
17$api->sendTransacEmail($message);

Resources