Releases: getbrevo/brevo-php
v4.0.13
v4.0.13
Bug fixes
getProcess / getProcesses — deserialization failure on completed processes (#121)
$duplicateEmailIdwas typed as?int, but the API returns a URL string pointing to a CSV file of duplicate IDs.- It is now typed as
?string.
getProcess / getProcesses — unknown status in_process (#122)
- The API still returns the legacy
in_processvalue (v3 name forprocessing). GetProcessResponseStatusandGetProcessesResponseProcessesItemStatusnow includeInProcess = "in_process", so deserialization no longer throws on active processes.
createEvent / createBatchEvents — boolean values rejected in contactProperties (#123)
contactPropertiesandeventPropertiesonly acceptedstring|int.- Boolean values (e.g.
'MY_FLAG' => true) now serialize correctly.
createContact / updateContact — integer values rejected in attributes (#124)
attributesvalues were typed asfloat|string|bool|array.- Passing a plain PHP
int(e.g.'OFFICE_ID' => 1234) now works without casting to(float).
v4.0.12
Summary
Resolved a field naming mismatch in the /orders/status/batch API response to align the implementation with the public contract.
Issue
During investigation of an L3 issue, a discrepancy was identified between the Swagger contract and the actual API response:
• Contract (Swagger): batchId (camelCase)
• Implementation: batch_id (snake_case)
This inconsistency caused misalignment with client expectations and SDK behavior.
Fix
• Updated the response format to use batchId (camelCase) as defined in the Swagger specification.
• Ensured consistency across API responses and documentation.
v4.0.11
What's Changed
New features
Events
- Added
getEvents()— retrieve a paginated list of custom events, filterable bycontactId,eventName,objectType,startDate, andendDate.
Supportslimit(default 100, max 10,000) andoffsetfor pagination.
Note: currently only supports custom events. - Added
createBatchEvents()— create multiple events in a single request using an array ofCreateBatchEventsRequestItem. Returns aBatchAcceptedResponse.
Ecommerce
CreateUpdateProductRequestand batch product upsert now accept two new optional fields:brandanddescription.
Balance
getActiveBalancesApi()now acceptsincludeInternalto include balances tied to internal definitions.getContactBalances()andgetSubscriptionBalances()now accept a request object with anincludeInternalparameter.getTransactionHistory()now supports filtering bystatus(draft,completed,rejected,cancelled,expired) andtransactionType(credit,debit).createBalanceDefinition()andupdateBalanceDefinition():- the
metafield is now a typed object (isInternal: bool) instead of a generic key-value array.
- the
CRM
- Added
PatchCrmAttributesIdRequestto update CRM attribute labels and selectable option labels.
Changes
Ecommerce
metaInfosize limit for products clarified: maximum 20,000 characters total (previously documented as 1,000 KB / max 20 items).
Account
usersfield on plan verticals is now nullable.
Bug fixes
createContact()no longer throws aBrevoException- Checks if the response body is empty and returns null instead of trying to deserialize it
- Only calls CreateContactResponse::fromJson($json) when there's actual content
v4.0.10
v4.0.10
Added
- Batch events endpoint —
$client->event->createBatchEvents()to track multiple contact interactions in a single request - Email campaign
excludeHtmlContentparameter —getEmailCampaign()accepts a new optional flag to omit the HTML body from the response, reducing payload size
Fixed
- Boolean attributes serialization —
UpdateContactRequestandCreateContactRequestnow correctly serialize boolean values in union-typed attribute maps (float | string | bool | array). Previously threwJsonException: Cannot serialize value of type boolean Order::productsitem type —OrderProductsItemnow correctly exposes all product fields:price,productId,variantId,quantity,quantityFloat. Previously onlyquantitywas accessibleGetCampaignStatsnullable fields —appleMppOpensandopensRateare now correctly typed as nullable (?int,?float), preventingTypeErrorwhen the API returnsnull
Deprecated
sendTransacSms()— UsesendAsyncTransactionalSms()instead. The synchronous method is deprecated. Note:remainingCreditsis intentionally not returned by the async endpoint; use the account endpoints to retrieve credit balance
Internal
- Generator updated from
2.1.4→2.1.10 - Fern CLI updated from
3.91.2→4.22.0
v4.0.7
What's Changed
Full Changelog: v4.0.6...v4.0.7
V4.0.6
What's Changed
Introduction of loyalty endpoint to delete member subscription.
New Contributors
Full Changelog: v4.0.5...v4.0.6
v4.0.5
📦 Brevo PHP SDK v4.0.5
Modernized, type-safe rewrite of the Brevo PHP client with a unified client architecture, PSR-18 compatibility, and built-in reliability features.
🚀 Highlights
- Type-safe SDK with strongly typed request/response objects and PHPDoc annotations
- Single unified client (
Brevo) replaces multiple API classes and manual configuration - Built-in retries + timeouts
- Structured error handling
- PSR-18 compatible — works with Guzzle, Symfony HttpClient, or any PSR-18 implementation
- PHP 8.1+ with support for Laravel, Symfony, and plain PHP
- Legacy v2.x now maintenance-only
⚠️ Breaking Changes
This is a full rewrite of the SDK. v4.0.5 is not backwards compatible with v2.x.
Key breaking changes:
- The multi-class initialization pattern (
Configuration::getDefaultConfiguration()+ per-API class instantiation) is replaced by a singleBrevoclient - Setter-based request building (e.g.,
$message->setSubject(...)) is replaced by typed request objects with named constructors - Error handling now uses
BrevoApiException/BrevoExceptioninstead of Guzzle-specific exceptions - The SDK now requires PHP 8.1+ (previously PHP 7.x)
- PSR-18 HTTP client replaces the hard Guzzle dependency
The legacy v2.x SDK will continue to receive critical security updates but no new features. We strongly recommend migrating to v4.x.
Added
New Client Architecture
- Introduced
Brevoas the single entry point - Namespaced API clients (e.g.,
$brevo->transactionalEmails->*,$brevo->contacts->*) - 30+ resource clients accessible from one instance: contacts, deals, campaigns, ecommerce, webhooks, and more
Type Safety
- Strongly typed request and response classes for every endpoint
- Full PHPDoc annotations for IDE autocomplete
- Named constructors with typed arrays replace untyped setters
Reliability Features
- Automatic retries with exponential backoff and jitter (~1s, ~2s, ~4s)
- Honors
Retry-Afterheaders on rate-limited responses - Configurable global and per-request timeouts (default: 60s)
- Retryable status codes:
408,429,500,502,503,504
Error Handling
BrevoApiExceptionfor all non-2xx API responses with:getCode()— HTTP status codegetMessage()— error messagegetBody()— parsed error response body
BrevoExceptionas a base for all SDK-level errors- Clean
try/catchbranching by status code
Advanced Configuration
- Custom PSR-18 HTTP client support (Guzzle, Symfony HttpClient, etc.)
- Custom headers at client and per-request level
- Configurable base URL
- Binary response support for file downloads
Runtime Compatibility
- PHP 8.1+
- Laravel
- Symfony
- Any framework or plain PHP project with Composer
Read more at https://developers.brevo.com/docs/api-clients/php
v4.0.3
📦 Brevo PHP SDK v4.0.3
Modernized, type-safe rewrite of the Brevo PHP client with a unified client architecture, PSR-18 compatibility, and built-in reliability features.
🚀 Highlights
- Type-safe SDK with strongly typed request/response objects and PHPDoc annotations
- Single unified client (
Brevo) replaces multiple API classes and manual configuration - Built-in retries + timeouts
- Structured error handling
- PSR-18 compatible — works with Guzzle, Symfony HttpClient, or any PSR-18 implementation
- PHP 8.1+ with support for Laravel, Symfony, and plain PHP
- Legacy v2.x now maintenance-only
⚠️ Breaking Changes
This is a full rewrite of the SDK. v4.0.3 is not backwards compatible with v2.x.
Key breaking changes:
- The multi-class initialization pattern (
Configuration::getDefaultConfiguration()+ per-API class instantiation) is replaced by a singleBrevoclient - Setter-based request building (e.g.,
$message->setSubject(...)) is replaced by typed request objects with named constructors - Error handling now uses
BrevoApiException/BrevoExceptioninstead of Guzzle-specific exceptions - The SDK now requires PHP 8.1+ (previously PHP 7.x)
- PSR-18 HTTP client replaces the hard Guzzle dependency
The legacy v2.x SDK will continue to receive critical security updates but no new features. We strongly recommend migrating to v4.x.
Added
New Client Architecture
- Introduced
Brevoas the single entry point - Namespaced API clients (e.g.,
$brevo->transactionalEmails->*,$brevo->contacts->*) - 30+ resource clients accessible from one instance: contacts, deals, campaigns, ecommerce, webhooks, and more
Type Safety
- Strongly typed request and response classes for every endpoint
- Full PHPDoc annotations for IDE autocomplete
- Named constructors with typed arrays replace untyped setters
Reliability Features
- Automatic retries with exponential backoff and jitter (~1s, ~2s, ~4s)
- Honors
Retry-Afterheaders on rate-limited responses - Configurable global and per-request timeouts (default: 60s)
- Retryable status codes:
408,429,500,502,503,504
Error Handling
BrevoApiExceptionfor all non-2xx API responses with:getCode()— HTTP status codegetMessage()— error messagegetBody()— parsed error response body
BrevoExceptionas a base for all SDK-level errors- Clean
try/catchbranching by status code
Advanced Configuration
- Custom PSR-18 HTTP client support (Guzzle, Symfony HttpClient, etc.)
- Custom headers at client and per-request level
- Configurable base URL
- Binary response support for file downloads
Runtime Compatibility
- PHP 8.1+
- Laravel
- Symfony
- Any framework or plain PHP project with Composer
Read more at https://developers.brevo.com/docs/api-clients/php
v2.0.14
What's Changed
- ON-7362: Contacts GetSegments API issue fixed by @jonirajput in #94
New Contributors
- @jonirajput made their first contribution in #94
Full Changelog: v2.0.13...v2.0.14
v2.0.13
What's Changed
- L3I-123501: Add in review status for email campaigns by @sowmyahora2001 in #87
Full Changelog: v2.0.12...v2.0.13