PHP SDK Changelog

Release history for the getbrevo/brevo-php SDK.

August 10, 2026 — v5.0.2

Added

  • Email Campaigns — UTM parameter customizationEmailCampaigns::createEmailCampaign() and EmailCampaigns::updateEmailCampaign() now accept optional utmCampaign, utmContent, and utmTerm fields in the request to customize UTM tracking parameters. Campaign retrieval methods return these values along with utmId, utmMedium, and utmSource when UTM tracking is enabled.
  • Transactional Email — per-contact pixel tracking consentTransactionalEmails::sendTransacEmail() now accepts optional contactPixelTrackingConsent boolean field on individual recipient objects (in to, cc, bcc, and messageVersions arrays) to control whether opens are tracked identifiably (true) or anonymized (false). When the per-contact pixel tracking consent feature is enabled for your account, this field determines tracking behavior per recipient.

Backward-compatible patch release. No breaking changes.

July 3, 2026 — v5.0.1

Added

  • Consent Groups Management — new endpoints for managing contact consent groups:
    • GET /contacts/consent-groups — list all consent groups
    • POST /contacts/consent-groups — create a consent group
    • GET /contacts/consent-groups/{id} — retrieve consent group details
    • PUT /contacts/consent-groups/{id} — update consent group (name, description, signup mode)
    • DELETE /contacts/consent-groups/{id} — delete a consent group
  • Consent group support in contact operationsPOST /contacts/import now accepts optional consentGroupIds to add imported contacts to specified groups
  • Contact details enhancementGET /contacts/{identifier} now returns consentGroups array showing each group and subscription status (when feature enabled)
  • Wallet pass installation URLsGET /wallet/passes/{passId}/installUrl/{contactId} generates per-contact installation URLs for Apple Wallet and Google Wallet integration

Fixed

  • Empty JSON object serializationJsonSerializableType now correctly serializes empty objects to {} instead of []. Previously, objects with all optional properties unset would serialize as empty arrays, causing backend validation errors on strict type checkers. This affected both top-level objects and nested objects within parent types. The fix ensures proper JSON structure for all empty serializable objects.

Backward-compatible patch release. No breaking changes.

June 15, 2026 — v4.0.16

Fixed

  • CreateBatchOrderResponse::batchId now deserializes correctly. The createBatchOrder endpoint returns the batch id as batch_id (snake_case), but the SDK looked for batchId, leaving it unset and throwing Cannot assign null to property ...::$batchId of type float on every call. The wire mapping is corrected to batch_id and the property is now nullable (?float). The $response->batchId accessor is unchanged.

Backward-compatible patch release. No breaking changes.

June 13, 2026 — v4.0.15

Fixed

  • GetCampaignStats count fields are now nullable (?int): clickers, complaints, delivered, hardBounces, sent, softBounces, trackableViews, uniqueClicks, uniqueViews, unsubscriptions, viewed. This model is reused for statsByDomain on getEmailCampaign(s), where per-domain rows are sparse and the API returns null or omits some counts. The previous non-nullable typing caused a TypeError while deserializing statsByDomain (globalStats was unaffected). (#138)

Backward-compatible patch release. No breaking changes.

June 12, 2026 — v4.0.14

Fixed

  • GetTransacBlockedContactsResponseContactsItem::senderEmail is now nullable (?string). The API returns null for some blocked or unsubscribed contacts, which previously caused a TypeError. (#137)
  • campaignId is now nullable (?int) on GetContactInfoResponseStatisticsUnsubscriptionsUserUnsubscriptionItem and GetContactStatsResponseUnsubscriptionsUserUnsubscriptionItem. Form-based (non-campaign) unsubscriptions return null, which previously caused a TypeError. (#136)
  • Guzzle timeout support — the PSR-18 client detection used class_exists on an interface and never matched; corrected to interface_exists, so the timeout option is now honored with a Guzzle client instead of emitting a warning. (#133)

Backward-compatible patch release. No breaking changes.

May 14, 2026 — v5.0.0

Breaking changes

  • ⚠️ GetCompaniesRequest::filters — renamed to filtersAttributesName. Existing code passing 'filters' => ... does not throw, but the filter is silently ignored server-side and the response is unfiltered.
  • Event::createBatchEvents — first argument changed from array to a CreateBatchEventsRequest wrapper.
  • Balance::getActiveBalancesApi — return type changed from ?BalanceLimit to ?GetLoyaltyBalanceProgramsPidActiveBalanceResponse (different shape).
  • Balance::getContactBalances$request no longer defaults to empty; balanceDefinitionId is required.
  • Balance\BeginTransactionRequest::eventTime — type changed from ?string to ?DateTime. ISO strings now cause TypeError.
  • Tasks::getAllTaskTypes — return type changed from ?GetCrmTasktypesResponse (wrapper) to ?array<GetCrmTasktypesResponseItem>.
  • EmailCampaigns\GetEmailCampaignResponse::utmIdActive renamed to utmId (wire key utmIDActiveutmID, type ?bool?int). Same change on GetEmailCampaignsResponseCampaignsItem.
  • Model fields removed: GetAccountResponse::dateTimePreferences, Webhook::channel, GetProcessResponseInfo::export, GetProcessResponse::error/createdAt/completedAt, and several ExternalFeeds response fields.
  • Process\GetProcessResponseInfoImport: count fields changed from ?int to ?string (now URLs to CSV reports) — affects invalidEmails, duplicateContactId, duplicateExtId, etc.
  • Ecommerce\CreateUpdateProductResponse::id and CreateUpdateCategoryResponse::id: ?int?string.
  • Several string date fields tightened to ?DateTime (Program::*, Reward::*, BalanceLimit::createdAt/updatedAt).
  • ConversationsMessageAttachmentsItem: fileNamename, inlineIdlink.
  • CustomObjects associations union flattened: UpsertrecordsRequestRecordsItemAssociationsItem is now a single class with action: 'link' | 'unlink' discriminator; 7 old variant classes deleted.

Added

  • New optional fields and filters across contacts->createContact, contacts->updateContact, emailCampaigns->getEmailCampaigns, ecommerce->getProducts, and several other endpoints.
  • Tier groups support upgrade and downgrade schedule fields.

See the Upgrading from v4.x guide for migration details and a one-line rollback pin.

April 10, 2026 — v4.0.13

Fixed

  • Process endpointsduplicate_email_id is now typed as a string (URL to a CSV file) instead of an integer. The legacy in_process status value is now handled correctly.
  • Event endpointscontact_properties and event_properties now accept boolean values in createEvent and createBatchEvents.
  • Contact endpointsattributes now accepts plain integers in createContact and updateContact. PHP users no longer need to cast integers to float.

March 25, 2026 — v4.0.11

Added

  • $client->event->getEvents() — retrieve a paginated list of custom events with filters for contact, event name, object type, and date range.
  • $client->event->createBatchEvents() — track multiple contact interactions in a single request.
  • PatchCrmAttributesIdRequest — update a CRM attribute’s display label and option labels.
  • CreateUpdateProductRequest and batch product upsert now accept optional brand and description fields.
  • Balance: getActiveBalancesApi(), getContactBalances(), and getSubscriptionBalances() now accept includeInternal.
  • Balance: getTransactionHistory() now supports filtering by status and transactionType.

Improved

  • meta field on balance definition requests is now a typed class instead of a generic array.
  • metaInfo size limit for products clarified: maximum 20,000 characters total.
  • users field on GetAccountResponsePlanVerticalsItem is now nullable.

Fixed

  • createContact() no longer throws BrevoException: Failed to deserialize response: Syntax error on empty success responses.

March 12, 2026 — v4.0.10

Added

  • Batch events endpoint: $client->event->createBatchEvents() to track multiple contact interactions in a single request.
  • getEmailCampaign() accepts a new optional excludeHtmlContent flag to omit the HTML body from the response.

Fixed

  • UpdateContactRequest and CreateContactRequest: boolean values in union-typed attribute maps now serialize correctly. Previously threw JsonException: Cannot serialize value of type boolean.
  • Order::products: OrderProductsItem now exposes all product fields — price, productId, variantId, quantity, quantityFloat.
  • GetCampaignStats: appleMppOpens and opensRate are now correctly typed as nullable (?int, ?float).

Deprecated

  • sendTransacSms() — use sendAsyncTransactionalSms() instead.

February 27, 2026 — v4.0 release

Released the PHP SDK v4 (getbrevo/brevo-php) with a type-safe client for the Brevo API.

$composer require getbrevo/brevo-php guzzlehttp/guzzle

Key highlights

  • Unified client via new Brevo(apiKey: "...") — single entry point with namespaced service clients
  • Strongly typed request and response objects with full PHPDoc annotations
  • PSR-18 HTTP client support — use Guzzle, Symfony HttpClient, or any compatible client
  • Automatic retries with exponential backoff (configurable per client or per request)
  • Structured errors via BrevoApiException with getCode(), getBody(), and getMessage()
  • 33 service namespaces covering the entire Brevo API