Skip to content

Releases: getbrevo/brevo-python

v5.0.0-rc.1

15 May 09:07
8e4188f

Choose a tag to compare

v5.0.0-rc.1

Release candidate for the v5 line. This pre-release is published so adopters can validate the new surface against their integrations before v5.0.0 is tagged stable. It is not picked up by pip install --upgrade automatically — opt in explicitly (see Installing this RC below).

If no blocking issues surface within the soak window, this build will be promoted to v5.0.0 unchanged.

pip install --pre "brevo-python>=5.0.0rc1,<6"

Status

  • Stability: rc — API surface is frozen. Only critical regressions discovered during soak will be patched into an rc2.
  • v4.x: remains supported and continues to receive wire-compatibility fixes.
  • Feedback welcome: please open an issue against getbrevo/brevo-python if you hit anything unexpected during migration. Tag with v5-rc.

Why this release

Most of the breaking changes in v5 come from an internal effort at Brevo to make our API endpoints, parameters and models more self-descriptive. The goal is to make the public surface easier to read at a glance — both for developers and for AI agents working against the Brevo API — so that names, shapes and required fields convey intent without needing to cross-reference external docs. Concretely, this means consistent snake_case keyword names, payload wrappers that reflect what the endpoint actually does (e.g. events= instead of request=), filter keys that match the wire format, model fields renamed or removed where the previous names were ambiguous, and shape collapses where a one-field pydantic wrapper added noise without value (Union[str, List[str]], Dict[str, int], etc.).

Every change applies symmetrically to both Brevo (sync) and AsyncBrevo.

We're aware that renaming costs callers a one-time migration, and we've kept v4.x supported so you can adopt v5 on your own timeline.

⚠️ Breaking changes

Companies — get_companies(filters=...) renamed

  • The filters keyword is renamed to filters_attributes_name to match the wire format.
  • The old keyword is silently dropped, the request still succeeds, and the server returns an unfiltered list. Audit every call site.

Events — event.create_batch_events payload renamed

  • Keyword renamed: request=events=.
  • Item types renamed in lockstep: CreateBatchEventsRequestItemCreateBatchEventsRequestEventsItem (and 5 sub-types).

Balance — get_contact_balances requires balance_definition_id

  • balance_definition_id is now a required parameter.

Balance — get_active_balances_api response shape changed

  • Response type replaced with GetLoyaltyBalanceProgramsPidActiveBalanceResponse (different shape).

Balance — begin_transaction.event_time type tightened

  • strdatetime. Runtime-tolerant under skip_validation, but type-checkers will fail.

CRM — tasks.get_all_task_types returns a list

  • Return type changed from GetCrmTasktypesResponse to List[GetCrmTasktypesResponseItem].
  • Old .id / .title access on the response now fails (it's a list).

Webhooks — create_webhook(events=...) is now optional / keyword-only

  • The events argument moved from required to optional. Positional callers break — switch to keyword arguments.

Webhooks — message_id is now a string

  • Type changed from int to str on history-fetch endpoints.

Response fields removed

  • GetAccountResponse.date_time_preferences
  • GetWebhook.channel
  • GetProcessResponseInfo.export

Shape collapses

  • SendTransacSmsTag is now Union[str, List[str]] (was a pydantic model).
  • GetExtendedCampaignStats.links_stats is now Dict[str, int] (was a pydantic class).
  • ConversationsMessageAttachmentsItem: file_namename, inline_idlink.

Top-level imports removed (21 names)

  • 21 names removed from top-level from brevo import .... Most notably:
    • CreateBatchEventsRequestItem* (6 names)
    • GetWebhookChannel
    • GetAccountResponseDateTimePreferences
    • GetExtendedCampaignStatsLinksStats
    • SendTransacSmsTagField
    • UpsertrecordsRequestRecordsItemAssociationsItemZero/One* (8 names)

Added

  • New optional fields and filters across contacts.create_contact, contacts.update_contact, email_campaigns.get_email_campaigns, ecommerce.get_products, and several other endpoints.
  • Both Brevo (sync) and AsyncBrevo are affected symmetrically by every change above.

Installing this RC

pip only installs pre-releases when you ask for them explicitly. Either:

pip install --pre "brevo-python>=5.0.0rc1,<6"

Or pin the exact RC build:

pip install "brevo-python==5.0.0rc1"

For requirements.txt-based projects, add the constraint and run pip with --pre:

brevo-python>=5.0.0rc1,<6

For Poetry / PDM, request the pre-release explicitly:

poetry add "brevo-python@^5.0.0-rc.1" --allow-prereleases

When v5.0.0 ships stable, pip install --upgrade brevo-python will swap this RC for the stable release automatically (the --pre flag is no longer needed once stable exists).

Holding on v4.x

If you're not ready to migrate, pin to v4:

pip install "brevo-python>=4,<5"

Migration

See the Upgrading from v4.x guide for full migration details.

Documentation

v4.0.10

10 Apr 14:08
28bb4b2

Choose a tag to compare

Bug fixes

get_process / get_processes — duplicate_email_id field type corrected

  • Changed from Optional[int] to Optional[str] to match the actual API response (a URL to a CSV file).

get_process / get_processes — in_process added to status literal

  • Both status types now include "in_process" in their Literal union, so deserialization no longer fails on active processes.

create_event / create_batch_events — contact_properties and event_properties accept booleans

  • Value type widened from Union[str, int] to Union[str, int, bool].

create_contact / update_contact — attributes accepts integers

  • Value type widened from Union[float, str, bool, List[str]] to Union[float, int, str, bool, List[str]], so plain int values no longer need to be cast to float.

v4.0.9

27 Mar 14:06
d255a74

Choose a tag to compare

v4.0.9

Bug fix

Fixed ApiError raised on create_contact when contact already exists (update_enabled=True)

When calling create_contact with update_enabled=True on an existing contact, the API correctly returns 204 No Content. The SDK was attempting to parse the empty response body as JSON, causing an unexpected ApiError instead of returning successfully. We are currently looking into additional modules which could result in similar behavior.

This no longer raises ApiError on the second call
client.contacts.create_contact(email=email, attributes={"USER_ID": 456}, update_enabled=True)

Thanks to @pouzet-pass for the detailed report #30

v4.0.8

25 Mar 08:59
17ee81a

Choose a tag to compare

New features

Events

  • Added get_events() — retrieve a paginated list of custom events, filterable by contact_id, event_name, object_type, start_date, and end_date.
    Note: currently only supports custom events.
  • Added create_batch_events() — create multiple events in a single request using the new CreateBatchEventsRequestItem type.

Ecommerce

  • create_update_product() and batch product upsert now accept two new optional fields: brand and description.

Balance

  • get_active_balances_api() now accepts an optional include_internal parameter to include balances tied to internal definitions.
  • get_transaction_history() now supports filtering by status and transaction_type (replaces the previous sort_field enum).
  • create_balance_definition() and update_balance_definition() now accept an optional meta field.

Changes

Ecommerce

  • metaInfo size limit for products clarified: maximum 20,000 characters total (previously documented as 1,000 KB / 20 items).

Account

  • users field on plan verticals is now nullable.

Bug fixes / corrections

  • InternalServerErrorBody and InternalServerErrorBodyCode error types are now exposed at the top-level package for consistent error handling.

v4.0.7

12 Mar 12:58
eed1bf5

Choose a tag to compare

v4.0.7

Added

  • Batch events endpointclient.event.create_batch_events() now available to track multiple contact interactions in a single request
  • Email campaign exclude_html_content parameterget_email_campaign() accepts a new optional flag to omit the HTML body from the response, reducing payload size

Fixed

  • GetAccountResponsePlanVerticalsItem.users nullableusers is now correctly typed as Optional[GetAccountResponsePlanVerticalsItemUsers], preventing TypeError when the API returns null for certain plan types
  • GetCampaignStats nullable fieldsapple_mpp_opens and opens_rate are now correctly typed as Optional[int] and Optional[float], preventing errors when the API returns null
  • OrderProductsItem all fieldsprice, product_id, variant_id, quantity, and quantity_float are all correctly exposed. Previously the type was incomplete
  • send_transac_sms marked deprecated — Use send_async_transactional_sms() instead

Internal

  • Generator updated to 4.63.3
  • Fern CLI updated to 4.22.0

v4.0.6

27 Feb 16:45
e1b3947

Choose a tag to compare

  • Added support for loyalty endpoint to delete membership.
  • Buf fixes and improvements

V4.0.5

20 Feb 16:31
1f461bd

Choose a tag to compare

brevo-python v4.0.3

PyPI

A complete rewrite of the Brevo Python SDK. The v4 SDK replaces the Swagger Codegen-based brevo_python module with a modern, Fern-generated brevo client built on httpx and pydantic.

This is a major release with breaking changes. See the migration guide below.

Installation

pip install brevo-python==4.0.1

What's new

  • Single client entry pointBrevo(api_key="...") replaces per-API class instantiation (AccountApi, ContactsApi, etc.)
  • Async support — native AsyncBrevo client for non-blocking calls
  • Typed models — Pydantic-based request/response objects with full type annotations
  • Automatic retries — exponential backoff on 408, 429, and 5xx (default: 2 retries)
  • Configurable timeouts — 60s default, overridable per-client or per-request
  • Raw response access — inspect headers and status codes via .with_raw_response
  • Custom HTTP client — pass your own httpx.Client for proxies, transports, or mTLS
  • Modern tooling — Poetry build system, mypy strict mode, ruff linting

Quick start

from brevo import Brevo

client = Brevo(api_key="YOUR_API_KEY")

account = client.account.get_your_account_information_plan_and_credits_details()
print(account)

Async usage

import asyncio
from brevo import AsyncBrevo

client = AsyncBrevo(api_key="YOUR_API_KEY")

async def main() -> None:
    account = await client.account.get_your_account_information_plan_and_credits_details()
    print(account)

asyncio.run(main())

Requirements

  • Python 3.8+ (Python 2.7 and 3.4-3.7 are no longer supported)
  • httpx >= 0.21.2
  • pydantic >= 1.9.2
  • typing_extensions >= 4.0.0

Breaking changes

Python version support

v1.x v4.x
Python 2.7, 3.4+ Python 3.8+

Import path

v1.x v4.x
import brevo_python from brevo import Brevo

Client initialization

# v1.x
import brevo_python
configuration = brevo_python.Configuration()
configuration.api_key['api-key'] = 'YOUR_API_KEY'
api_instance = brevo_python.AccountApi(brevo_python.ApiClient(configuration))
api_response = api_instance.get_account()

# v4.x
from brevo import Brevo
client = Brevo(api_key="YOUR_API_KEY")
account = client.account.get_your_account_information_plan_and_credits_details()

Error handling

# v1.x
from brevo_python.rest import ApiException
try:
    api_response = api_instance.get_account()
except ApiException as e:
    print("Exception: %s\n" % e)

# v4.x
from brevo.core.api_error import ApiError
try:
    account = client.account.get_your_account_information_plan_and_credits_details()
except ApiError as e:
    print(e.status_code)
    print(e.body)

HTTP library

v1.x v4.x
urllib3 (via Swagger Codegen) httpx
No async support AsyncBrevo with httpx.AsyncClient

Build system

v1.x v4.x
setup.py pyproject.toml (Poetry)
requirements.txt with urllib3, certifi, six httpx, pydantic, typing_extensions

Summary of all breaking changes

Area v1.x (brevo_python) v4.x (brevo)
Module import brevo_python from brevo import Brevo
Client AccountApi(ApiClient(config)) Brevo(api_key="...")
Config Configuration() + api_key['api-key'] Constructor parameter api_key
Errors ApiException ApiError with .status_code, .body
HTTP urllib3 httpx
Async Not available AsyncBrevo
Retries Not built-in Automatic with exponential backoff
Timeouts Manual 60s default, configurable
Python 2.7, 3.4+ 3.8+
Build setup.py pyproject.toml (Poetry)
Generator Swagger Codegen Fern

Migrating from v1.x

Step 1 — Update the package

pip install --upgrade brevo-python==4.0.0

Step 2 — Update imports

Replace all brevo_python imports:

# Before
import brevo_python
from brevo_python.rest import ApiException

# After
from brevo import Brevo
from brevo.core.api_error import ApiError

Step 3 — Replace client initialization

Remove Configuration and ApiClient boilerplate:

# Before
configuration = brevo_python.Configuration()
configuration.api_key['api-key'] = 'YOUR_API_KEY'
api_instance = brevo_python.ContactsApi(brevo_python.ApiClient(configuration))

# After
client = Brevo(api_key="YOUR_API_KEY")

Step 4 — Update API calls

Methods are now accessed through namespaced properties on a single client:

# Before
contacts_api = brevo_python.ContactsApi(brevo_python.ApiClient(configuration))
result = contacts_api.get_contacts()

email_api = brevo_python.TransactionalEmailsApi(brevo_python.ApiClient(configuration))
email_api.send_transac_email(message)

# After
result = client.contacts.get_all_the_contacts()
client.transactional_emails.send_a_transactional_email(...)

Step 5 — Update error handling

# Before
from brevo_python.rest import ApiException
try:
    api_response = api_instance.get_account()
except ApiException as e:
    print("Exception: %s\n" % e)

# After
from brevo.core.api_error import ApiError
try:
    account = client.account.get_your_account_information_plan_and_credits_details()
except ApiError as e:
    print(e.status_code)
    print(e.body)

Deprecation notice

The v1.x SDK on the main branch will continue to receive critical security patches but no new features or API coverage updates. All new development targets v4.x on the v4 branch.

Links

v1.2.0

13 Jul 15:12
4750bcf

Choose a tag to compare

What's Changed

  • Sync with all the latest updates.

https://developers.brevo.com/reference/getting-started-1

v1.1.2

15 Jul 10:53
a363448

Choose a tag to compare

What's Changed

Full Changelog: v1.1.1...v1.1.2

v1.1.1

28 Jun 12:22
e3210b8

Choose a tag to compare

What's Changed

New API's added:

  • Coupons.
  • Deals.
  • Ecommerce.
  • Events.
  • Master account.
  • Payments.
  • User.

https://developers.brevo.com/reference/getting-started-1