March 25, 2026

SDK updates: Node.js v5.0.3, PHP v4.0.11, Python v4.0.9

New endpoints, new fields, and API improvements across all three SDKs.

Node.js — @getbrevo/brevo v5.0.3

Added

  • client.event.getEvents() — retrieve a paginated list of custom events, filterable by contact_id, event_name, object_type, startDate, and endDate. Currently only supports custom events.
  • client.event.createBatchEvents() — send multiple events in a single request. Returns a BatchAcceptedResponse with a confirmation message and queued event count.
  • client.companies.deleteAnAttribute() — delete a CRM attribute by ID.
  • PatchCrmAttributesIdRequest — update a CRM attribute’s display label and selectable option labels, scoped to companies or deals.
  • GetProductDetails response now includes brand and description.
  • CreateUpdateProductRequest and batch product upsert now accept optional brand and description fields.
  • Balance: getActiveBalancesApi(), getContactBalances(), and getSubscriptionBalances() now accept an optional includeInternal parameter.
  • Balance: getTransactionHistory() now supports filtering by status and transactionType.

Improved

  • meta field on balance definition requests is now a typed object ({ isInternal?: boolean }) instead of a generic Record<string, unknown>.
  • metaInfo size limit for products clarified: maximum 20,000 characters total.
  • users field on plan verticals is now nullable (Item.Users | null).

PHP — getbrevo/brevo-php 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. Currently only supports custom events.
  • $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.

Python — brevo-python v4.0.9

Added

  • client.event.get_events() — retrieve a paginated list of custom events with filters for contact, event name, object type, and date range. Currently only supports custom events.
  • client.event.create_batch_events() — track multiple contact interactions in a single request.
  • CreateUpdateProductRequest and batch product upsert now accept optional brand and description fields.
  • GetProductDetails response now includes brand and description.
  • Balance: get_active_balances_api(), get_contact_balances(), and get_subscription_balances() now accept include_internal.
  • Balance: get_transaction_history() now supports filtering by status and transaction_type.

Improved

  • meta field on balance definition requests is now a typed model with an is_internal flag.
  • metaInfo size limit for products clarified: maximum 20,000 characters total.
  • users field on plan verticals is now nullable.

March 21, 2026

Ecommerce, Events, and Loyalty API updates

Ecommerce — New product fields

Two new fields are now supported on the POST /products and POST /products/batch endpoints, as well as the GET /products/{id} response:

  • brand — Brand name of the product. String, max 128 characters. Example: "Adidas".
  • description — Description of the product. String, max 3000 characters. Example: "Shoes for sports".

metaInfo limit updated: The size limit for the metaInfo field has changed from 1000 KB to 20,000 characters (total across all keys and values). The maximum number of keys remains 20.

Events API — New GET endpoint

A new GET /events endpoint is available to retrieve events filtered by contact, name, object type, or date range.

Query parameters:

ParameterDescription
contact_idFilter by contact ID (repeatable)
event_nameFilter by event name (repeatable)
object_typeFilter by object type (repeatable)
startDate / endDateDate range filter (YYYY-MM-DD or RFC3339). Defaults to the past 6 months.
limitMax events to return. Default 100, max 10000.
offsetEvents to skip for pagination. Default 0.

The response includes a count field for pagination and an events array sorted by event_date descending.

See Event endpoints for the full reference.

Events API — Batch events breaking changes

These are breaking changes to the POST /events/batch endpoint.

Response code changed: 204202

Successful batch requests now return 202 Accepted instead of 204 No Content. The response body is no longer empty — it returns a JSON object:

1{
2 "message": "Batch accepted. Valid events have been added to the processing queue.",
3 "count": 7
4}

Update any client code that checks for 204 on batch event responses.

Partial success status renamed: partialSuccesspartiallyQueued

The status field in the 207 partial success response body has been renamed from partialSuccess to partiallyQueued. Update any client code parsing this field.

Loyalty — Internal balance definitions and tier groups

Balance definitions and tier groups now support a meta object with an isInternal flag:

1"meta": {
2 "isInternal": true
3}

Internal balance definitions are excluded from member-facing balance reads by default. Pass includeInternal=true as a query parameter to include them.

The includeInternal query parameter is available on the following endpoints:

  • GET /loyalty/config/programs/{pid}/balance-definitions
  • GET /loyalty/balance/programs/{pid}/subscriptions/{cid}/balances
  • GET /loyalty/balance/programs/{pid}/balances
  • GET /loyalty/config/programs/{pid}/members

Loyalty — Transaction list filters

The transaction history endpoint (GET /loyalty/balance/programs/{pid}/subscriptions/{cid}/transactions) now supports additional query parameters:

ParameterDescription
statusFilter by status: draft, completed, rejected, cancelled, expired
transactionTypeFilter by type: credit or debit

The offset parameter now represents a page number (not a record skip count).


March 12, 2026

SDK updates: Node.js v5.0.1, PHP v4.0.10, Python v4.0.7

Bug fixes, type corrections, and a deprecation across all three SDKs.

Node.js — @getbrevo/brevo v5.0.1

Fixed

  • GetCampaignStats: appleMppOpens and opensRate are now typed as number | null. The API returns null when no data is available for the campaign period.
  • Order.products: the full set of product fields is now exposed — price, productId, variantId, quantity, and quantityFloat. Previously only quantity was available.
  • GetAccountResponsePlanVerticalsItem.users: now typed as optional/nullable, matching API behavior on certain plan types.
  • createContact(): no longer throws a JSON parse error on 204 No Content responses (returned when a contact already exists).

Deprecated

  • transactionalSms.sendTransacSms() — use transactionalSms.sendTransacSmsAsync() instead. The synchronous variant adds latency by waiting for carrier acknowledgment.

PHP — getbrevo/brevo-php 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.

Python — brevo-python v4.0.7

Fixed

  • GetCampaignStats: apple_mpp_opens and opens_rate are now correctly typed as nullable.
  • Order.products: all product fields are now accessible — price, product_id, variant_id, quantity, quantity_float.
  • create_contact(): correctly handles 204 No Content responses without raising a deserialization error.

Deprecated

  • transactional_sms.send_transac_sms() — use transactional_sms.send_transac_sms_async() instead.

Loyalty API guides

Added a new Loyalty section to the Guides tab with six pages covering the full Loyalty API integration workflow.

The existing Loyalty webhooks page has been enriched with a complete event reference table and recommended automations for each event.


Batch event creation

Added POST /events/batch to the Events API. This endpoint allows sending multiple events in a single request, each with its own contact identifiers, event properties, and optional object associations.

The response supports partial success — if some events fail validation, the API returns a 207 status with a breakdown of successful and failed events, including per-event error messages.

Read more in the reference section


Brevo MCP server — security and configuration update

The Brevo MCP server has been updated with improved security, simplified maintenance, and rate limiting.

What changed:

  • Authentication method: MCP tokens are no longer passed in the URL. They are now transmitted securely via the HTTP Authorization: Bearer <token> header. All previous URL patterns containing /{token} are no longer valid.
  • Auto-generated tools: The 193 MCP tools are now automatically generated from the Brevo OpenAPI specification, eliminating discrepancies between the API and MCP server.
  • Rate limiting: Request limits have been added to protect services from abuse.
  • New tool support: Integration guides now cover Windsurf, VS Code (GitHub Copilot), and Claude Code CLI in addition to Claude Desktop, Cursor, and Cline.

Action required: Update your MCP configuration to use the new header-based authentication. See the integration guide for updated configuration examples for all supported tools.


February 27, 2026

Loyalty API: new endpoint and rate limits

New endpoint: DELETE /loyalty/config/programs/{pid}/contact/{cid}

Removes a contact from a loyalty program subscription. See the Loyalty API reference for details.

Rate limits: Loyalty endpoints now have documented rate limits across all account tiers.

EndpointsStarterBusinessEnterprise
GET /v3/loyalty/config
All endpoints under /v3/loyalty/{…}
600 RPH1,200 RPH3,600 RPH

See the rate limits documentation for the full breakdown.

PHP SDK v4 release

We’ve released the PHP SDK v4 (getbrevo/brevo-php) with a type-safe client for the Brevo API: unified Brevo client, strongly typed request and response objects with PHPDoc annotations, PSR-18 HTTP client compatibility (Guzzle, Symfony HttpClient), automatic retries with exponential backoff, and structured error handling via BrevoApiException.

You can learn more on the dedicated guide here: https://developers.brevo.com/docs/api-clients/php

Install it using:

$composer require getbrevo/brevo-php

Guzzle is recommended as the HTTP client:

$composer require getbrevo/brevo-php guzzlehttp/guzzle

Key highlights:

  • Unified client via 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

Resources:


Python SDK v4 beta release

We’ve released a beta version of the Python SDK (v4.0) with significant improvements including native async support via AsyncBrevo, Pydantic-based typed models, automatic retries with exponential backoff, and a custom httpx client support.

You can learn more on the dedicated guide here: https://developers.brevo.com/docs/api-clients/python

Install it using:

$pip install brevo-python

Key highlights:

  • Unified client via Brevo(api_key="...") — no more manual configuration objects
  • Native async support with AsyncBrevo
  • Full type annotations for all request and response models
  • Raw response access via with_raw_response
  • 33 service namespaces covering the entire Brevo API

Resources:


Conversations webhooks documentation update

Updated the Conversations webhooks documentation with new fields and corrections.

Message object — new fields:

  • rawUnsafeHtml — Raw unsanitized HTML of the message
  • subject — Email subject line (present for email-source conversations)
  • isSentViaJsApitrue for messages sent via the JS API
  • sourceMessageId — Original message ID from the source platform
  • from, to, replyTo, cc, bcc — Email conversation fields
  • isForwardtrue if the message is a forwarded message

Attachment object — new fields:

  • mimeType — MIME type of the file
  • isInline — Whether the attachment is inline (e.g. embedded images in emails)
  • inlineId — Content-ID for inline attachments

Visitor object — new field:

  • isBanned — Whether the visitor is banned (in conversationTranscript only)

Corrections:

  • imageInfo.previewUrl renamed to imageInfo.previewLink in the conversation transcript payload
  • Image preview URL quality parameter updated from lighter to better

Node.js SDK beta release

We’ve released a beta version of the Node.js SDK (v4.0.1) with significant improvements including a promise-based API, enhanced TypeScript types, standardized error handling, and improved retry logic. You can learn more on the dedicated guide here: https://developers.brevo.com/docs/api-clients/node-js

The pre-release is now available on npm. Install it using:

$npm install @getbrevo/brevo@^4.0.1
$npm install @getbrevo/brevo@^next

Resources: