The Brevo PHP SDK (getbrevo/brevo-php) is a type-safe client library for the Brevo API. It provides:
Brevo client with namespaced service clientsBrevoApiExceptionVersion 5.0 introduces breaking changes versus v4.x. v4.x remains supported and continues to receive wire-compatibility fixes — see the changelog for the list of changes and the README for migration steps.
ext-jsonInstall the SDK using Composer:
Guzzle is recommended as the HTTP client:
If no HTTP client is provided, the SDK uses php-http/discovery to auto-detect an installed PSR-18 client.
Initialize the client and send your first email:
Pass an options array as the second argument to configure the client:
BrevoApiException is thrown for any non-2xx HTTP response. Catch it to inspect the status code and response body:
BrevoApiException exposes:
getCode() — HTTP status codegetMessage() — Error messagegetBody() — Parsed response bodyAutomatic retries with exponential backoff are enabled by default (2 retries). Configure at the client or request level:
408, 429, 5xxRetry-After and X-RateLimit-Reset response headersNo 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:
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.
The timeout, maxRetries, and headers options can be overridden per request by passing an options array as the last argument:
Pass query parameters via the typed request object:
Some endpoints (e.g., attachment downloads) return binary content directly:
All request and response objects are strongly typed. Use the generated request classes for IDE autocomplete and static analysis:
Pass any PSR-18-compatible client via the client option:
Register the client as a singleton in a service provider:
The SDK doesn’t ship a built-in logger. Instead, it routes every request through the PSR-18 HTTP client you pass via the client option, which means you can plug in any PSR-3 logger (Monolog, Symfony Logger, Laravel’s Log facade, etc.) by wrapping that client with logging middleware.
This keeps the SDK lean and lets you reuse the logger your application already configures.
Logging happens at the HTTP layer, so each Brevo SDK call produces a log line per HTTP request — including retries, which the SDK performs internally. Use the message formatter to control verbosity (method/URI only, full headers, request and response bodies, timing, etc.).
Middleware::log placeholders worth knowing:
The api-key header is sent on every request. If you log request headers, redact it before writing to disk or shipping to an external sink. The simplest approach is a custom middleware that strips the header before the log middleware runs.
Symfony’s Psr18Client accepts a PSR-3 logger via the underlying HttpClient. It logs requests, responses, and retries automatically — no middleware wiring required.
Reuse Laravel’s configured logger by resolving it from the service container when you build the Brevo client:
Any object implementing Psr\Log\LoggerInterface works with Guzzle’s Middleware::log. This lets you drop the SDK into projects that use Monolog, the Symfony Logger, Laminas Log, or a hand-rolled PSR-3 implementation without changing the SDK call sites.
Avoid hardcoding API keys. Use environment variables:
In Laravel, use config('services.brevo.api_key'). In Symfony, use $_ENV['BREVO_API_KEY'] or service parameters.
For large operations (bulk exports, large attachments), adjust PHP’s memory_limit:
The unified Brevo client exposes the following service namespaces: