For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Help CenterAPI KeysStatusSign In
GuidesAPI ReferenceChangelog
GuidesAPI ReferenceChangelog
  • Getting started
    • Overview
    • Quickstart
    • Authentication
    • Rate limits
        • Overview
        • Node.js
        • Python
          • Changelog
        • PHP
      • Connect to Cursor
  • Messaging API
    • Send transactional email
    • Send transactional SMS
    • Send transactional WhatsApp
  • Marketing Platform
    • Manage your contacts
    • Track website activity
    • Send WhatsApp campaigns
    • Weekly event exports
  • Webhooks
    • Getting started
    • Conversations webhooks
    • Payment webhooks
    • Marketing webhooks
    • Transactional webhooks
    • Loyalty webhooks
    • Batched webhooks
    • Secure webhook calls
    • Meetings and phone webhooks
    • Push notification webhooks
    • Sales CRM webhooks
  • Conversations
    • Getting started
    • Customize the chat widget
    • JavaScript API reference
    • REST API reference
    • Conversations webhooks
  • eCommerce
    • Activate eCommerce app
    • Manage product categories
    • Manage products
    • Manage orders
    • Coupon collections
    • eCommerce tracker events
  • Loyalty
    • Overview
    • Set up a program
    • Enroll members
    • Credit & debit points
    • Read member data
    • Best practices
  • Custom Objects
    • Custom objects management
  • Brevo tracker and events
    • Getting started
    • JavaScript implementation
    • REST implementation
    • Legacy tracker documentation
    • Events
  • Accounts and settings
    • Senders and domains
    • User activity logs
    • External feeds
    • Invited users
LogoLogo
Help CenterAPI KeysStatusSign In
On this page
  • Overview
  • Requirements
  • Installation
  • Quick start
  • Configuration
  • Constructor parameters
  • Async client
  • Error handling
  • Error classes
  • Retries
  • Retry behavior
  • Timeouts
  • Recommended timeout values
  • Request options
  • Raw response access
  • Logging
  • LogConfig fields
  • Custom logger
  • Integrations
  • Custom HTTP client
  • Common integrations
  • Available services
  • Migration from v1.x
  • Key changes
  • Migration example
  • Resources
Getting startedSDKs and AI toolsSupported programming languages

Python SDK

Learn how to integrate the Brevo API into your Python applications.
Was this page helpful?
Previous

Python SDK Changelog

Release history for the brevo-python SDK.

Next
Built with

Overview

The Brevo Python SDK (brevo-python) is a fully typed client library for the Brevo API. It provides:

  • A unified Brevo client with namespaced service clients
  • Native async support via AsyncBrevo
  • Pydantic-based typed models with full type annotations
  • Automatic retries with exponential backoff
  • Raw response access with headers and status codes
  • Custom httpx client support for proxies and mTLS

PyPI

Version 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.

Requirements

  • Python 3.8+
  • httpx >= 0.21.2
  • pydantic >= 1.9.2
  • typing_extensions >= 4.0.0

Installation

$pip install brevo-python

Quick start

Initialize the client and send your first email:

quick_start.py
1from brevo import Brevo
2from brevo.transactional_emails import (
3 SendTransacEmailRequestSender,
4 SendTransacEmailRequestToItem,
5)
6
7client = Brevo(api_key="your-api-key")
8
9result = client.transactional_emails.send_transac_email(
10 subject="Hello from Brevo!",
11 html_content="<html><body><p>Hello,</p><p>This is my first transactional email.</p></body></html>",
12 sender=SendTransacEmailRequestSender(
13 name="Alex from Brevo",
14 email="hello@brevo.com",
15 ),
16 to=[
17 SendTransacEmailRequestToItem(
18 email="johndoe@example.com",
19 name="John Doe",
20 )
21 ],
22)
23
24print("Email sent. Message ID:", result.message_id)

Configuration

Pass keyword arguments to the constructor to configure the client:

configuration.py
1from brevo import Brevo
2
3client = Brevo(
4 api_key="your-api-key",
5 timeout=30.0,
6)

Constructor parameters

ParameterTypeDefaultDescription
api_keystrRequiredYour Brevo API key
timeoutfloat60.0Default request timeout in seconds
base_urlstrNoneOverride the default API base URL
follow_redirectsboolTrueFollow HTTP redirects
httpx_clienthttpx.ClientNoneCustom httpx client instance
headersdictNoneAdditional default headers sent with every request
loggingLogConfig | LoggerNoneLogging configuration (see Logging)

Async client

Use AsyncBrevo for non-blocking calls. Pass httpx.AsyncClient instead of httpx.Client when providing a custom HTTP client:

async_client.py
1import asyncio
2from brevo import AsyncBrevo
3from brevo.transactional_emails import (
4 SendTransacEmailRequestSender,
5 SendTransacEmailRequestToItem,
6)
7
8client = AsyncBrevo(api_key="your-api-key")
9
10async def main() -> None:
11 result = await client.transactional_emails.send_transac_email(
12 subject="Hello from Brevo!",
13 html_content="<html><body><p>Hello!</p></body></html>",
14 sender=SendTransacEmailRequestSender(
15 name="Alex from Brevo",
16 email="hello@brevo.com",
17 ),
18 to=[
19 SendTransacEmailRequestToItem(
20 email="johndoe@example.com",
21 name="John Doe",
22 )
23 ],
24 )
25 print("Email sent. Message ID:", result.message_id)
26
27asyncio.run(main())

Error handling

The SDK raises ApiError (or a typed subclass) for non-2xx HTTP responses:

error_handling.py
1from brevo import Brevo
2from brevo.core.api_error import ApiError
3
4client = Brevo(api_key="your-api-key")
5
6try:
7 client.transactional_emails.send_transac_email(...)
8except ApiError as e:
9 print(e.status_code)
10 print(e.body)

Error classes

Status codeClass
400BadRequestError
401UnauthorizedError
402PaymentRequiredError
403ForbiddenError
404NotFoundError
405MethodNotAllowedError
409ConflictError
412PreconditionFailedError
415UnsupportedMediaTypeError
422UnprocessableEntityError
424FailedDependencyError
429TooManyRequestsError
500InternalServerError

All ApiError instances expose:

  • status_code — HTTP status code
  • body — Parsed response body
  • headers — Response headers

Retries

Automatic retries with exponential backoff are enabled by default (2 retries). Configure at the client or request level:

retries.py
1from brevo import Brevo
2
3# Client-level (not directly supported — use request_options per request)
4client = Brevo(api_key="your-api-key")
5
6# Request-level
7client.transactional_emails.send_transac_email(
8 ...,
9 request_options={"max_retries": 3},
10)

Retry behavior

  • Retryable status codes: 408, 429, 5xx
  • Backoff: Exponential with jitter
  • Disable: Set max_retries: 0 in request_options

Timeouts

Default timeout is 60 seconds. Configure at the client or request level:

timeouts.py
1from brevo import Brevo
2
3# Client-level
4client = Brevo(
5 api_key="your-api-key",
6 timeout=30.0,
7)
8
9# Request-level
10client.transactional_emails.send_transac_email(
11 ...,
12 request_options={"timeout_in_seconds": 10},
13)

Recommended timeout values

Use caseTimeout
Standard API calls30–60s (default)
Quick operations10–15s
Bulk operations120–300s
Real-time / low-latency5–10s

Request options

All service methods accept a request_options dict as the final keyword argument:

OptionTypeDescription
timeout_in_secondsintOverride timeout for this request
max_retriesintOverride max retries for this request
additional_headersdictMerge additional headers into the request
additional_query_parametersdictAdd query parameters to the request
additional_body_parametersdictAdd body parameters to the request
request_options.py
1client.transactional_emails.send_transac_email(
2 ...,
3 request_options={
4 "timeout_in_seconds": 10,
5 "max_retries": 1,
6 "additional_headers": {"X-Custom-Header": "custom-value"},
7 },
8)

Raw response access

Access response headers and status code via .with_raw_response:

raw_response.py
1from brevo import Brevo
2
3client = Brevo(api_key="your-api-key")
4
5response = client.transactional_emails.with_raw_response.send_transac_email(...)
6
7print(response.status_code)
8print(response.headers)
9print(response.data)

Logging

The SDK has a built-in, opt-in logger you can plug your own implementation into. Pass a LogConfig dict (or a pre-built Logger) via the logging constructor option.

By default the SDK is silent: nothing is logged unless you set silent=False. This keeps integration changes from accidentally producing log volume in production.

logging_basic.py
1from brevo import Brevo
2from brevo.core.logging import ConsoleLogger
3
4client = Brevo(
5 api_key="your-api-key",
6 logging={
7 "level": "debug", # "debug" | "info" | "warn" | "error"
8 "logger": ConsoleLogger(), # built-in; writes to stdlib `logging` under the "fern" logger
9 "silent": False, # required to actually emit logs
10 },
11)

LogConfig fields

FieldTypeDefaultDescription
level"debug" | "info" | "warn" | "error""info"Minimum level that gets forwarded to the logger
loggerILoggerConsoleLogger()Logger implementation — any object conforming to the ILogger protocol
silentboolTrueWhen True, all logging is suppressed regardless of level

Custom logger

Implement the ILogger protocol (a typing.Protocol with debug, info, warn, error methods) to forward to any logging library — Python’s stdlib logging, structlog, loguru, or your own sink.

custom_logger.py
1import logging
2from brevo import Brevo
3from brevo.core.logging import ILogger
4
5logging.basicConfig(level=logging.DEBUG)
6
7class StdlibLogger(ILogger):
8 def __init__(self, name: str = "brevo") -> None:
9 self._log = logging.getLogger(name)
10
11 def debug(self, message: str, **kwargs) -> None: self._log.debug(message, extra=kwargs)
12 def info(self, message: str, **kwargs) -> None: self._log.info(message, extra=kwargs)
13 def warn(self, message: str, **kwargs) -> None: self._log.warning(message, extra=kwargs)
14 def error(self, message: str, **kwargs) -> None: self._log.error(message, extra=kwargs)
15
16client = Brevo(
17 api_key="your-api-key",
18 logging={"level": "debug", "logger": StdlibLogger(), "silent": False},
19)

Integrations

structlog
1import structlog
2from brevo import Brevo
3from brevo.core.logging import ILogger
4
5class StructlogLogger(ILogger):
6 def __init__(self) -> None:
7 self._log = structlog.get_logger("brevo")
8
9 def debug(self, message, **kwargs): self._log.debug(message, **kwargs)
10 def info(self, message, **kwargs): self._log.info(message, **kwargs)
11 def warn(self, message, **kwargs): self._log.warning(message, **kwargs)
12 def error(self, message, **kwargs): self._log.error(message, **kwargs)
13
14client = Brevo(
15 api_key="your-api-key",
16 logging={"level": "info", "logger": StructlogLogger(), "silent": False},
17)
loguru
1from loguru import logger
2from brevo import Brevo
3from brevo.core.logging import ILogger
4
5class LoguruLogger(ILogger):
6 def debug(self, message, **kwargs): logger.bind(**kwargs).debug(message)
7 def info(self, message, **kwargs): logger.bind(**kwargs).info(message)
8 def warn(self, message, **kwargs): logger.bind(**kwargs).warning(message)
9 def error(self, message, **kwargs): logger.bind(**kwargs).error(message)
10
11client = Brevo(
12 api_key="your-api-key",
13 logging={"level": "debug", "logger": LoguruLogger(), "silent": False},
14)
Reusing a pre-built Logger

Build a Logger once and reuse it across Brevo and AsyncBrevo instances:

1from brevo import Brevo, AsyncBrevo
2from brevo.core.logging import Logger, ConsoleLogger
3
4shared = Logger(level="info", logger=ConsoleLogger(), silent=False)
5
6sync_client = Brevo(api_key="your-api-key", logging=shared)
7async_client = AsyncBrevo(api_key="your-api-key", logging=shared)

The default ConsoleLogger uses Python’s stdlib logging module under the logger name "fern". If you only need to filter or reformat output, configuring that logger via logging.getLogger("fern") may be enough — you don’t always need a custom ILogger.

Custom HTTP client

Override the default httpx client for proxies, custom transports, or mTLS:

custom_http_client.py
1import httpx
2from brevo import Brevo
3
4client = Brevo(
5 api_key="your-api-key",
6 httpx_client=httpx.Client(
7 proxy="http://my.test.proxy.example.com",
8 transport=httpx.HTTPTransport(local_address="0.0.0.0"),
9 ),
10)

Common integrations

Async with custom client
1import httpx
2from brevo import AsyncBrevo
3
4client = AsyncBrevo(
5 api_key="your-api-key",
6 httpx_client=httpx.AsyncClient(
7 proxy="http://my.test.proxy.example.com",
8 ),
9)
Custom timeout and transport
1import httpx
2from brevo import Brevo
3
4client = Brevo(
5 api_key="your-api-key",
6 httpx_client=httpx.Client(
7 timeout=httpx.Timeout(120.0, connect=10.0),
8 transport=httpx.HTTPTransport(retries=3),
9 ),
10)
With event hooks
1import httpx
2from brevo import Brevo
3
4def log_request(request: httpx.Request) -> None:
5 print(f"→ {request.method} {request.url}")
6
7def log_response(response: httpx.Response) -> None:
8 print(f"← {response.status_code}")
9
10client = Brevo(
11 api_key="your-api-key",
12 httpx_client=httpx.Client(
13 event_hooks={"request": [log_request], "response": [log_response]},
14 ),
15)

Available services

The Brevo and AsyncBrevo clients expose the following service namespaces:

PropertyDescription
transactional_emailsSend emails, manage templates, blocked contacts and domains
transactional_smsSend SMS messages and view delivery statistics
transactional_whats_appSend WhatsApp messages and view event reports
sms_templatesManage SMS templates
contactsManage contacts, lists, folders, attributes and segments
email_campaignsCreate and manage email marketing campaigns
sms_campaignsCreate and manage SMS marketing campaigns
whats_app_campaignsCreate and manage WhatsApp campaigns and templates
companiesManage CRM companies
dealsManage CRM deals and pipelines
tasksManage CRM tasks
notesManage CRM notes
filesUpload and manage CRM files
conversationsManage conversation messages and automated messages
ecommerceManage products, categories, orders and attribution
couponsManage coupon collections and coupons
paymentsCreate and manage payment requests
eventTrack custom events
webhooksManage webhooks
sendersManage senders and IPs
domainsManage and authenticate domains
accountRetrieve account information and activity logs
inbound_parsingRetrieve inbound email events and attachments
custom_objectsManage custom object records
external_feedsManage external RSS feeds
master_accountManage sub-accounts and groups (enterprise)
userManage users and permissions
processRetrieve background process status
programManage loyalty programs
balanceManage loyalty balances and transactions
rewardManage loyalty rewards and vouchers
tierManage loyalty tiers and tier groups

Migration from v1.x

Key changes

Areav1.x (brevo_python)v4.x (brevo)
Moduleimport brevo_pythonfrom brevo import Brevo
ClientAccountApi(ApiClient(config))Brevo(api_key="...")
ConfigConfiguration() + api_key['api-key']Constructor parameter api_key
ErrorsApiExceptionApiError with .status_code, .body
HTTPurllib3httpx
AsyncNot availableAsyncBrevo
RetriesNot built-inAutomatic with exponential backoff
TimeoutsManual60s default, configurable
Python2.7, 3.4+3.8+

Migration example

1# v1.x
2import brevo_python
3from brevo_python.rest import ApiException
4
5configuration = brevo_python.Configuration()
6configuration.api_key['api-key'] = 'YOUR_API_KEY'
7
8api_instance = brevo_python.AccountApi(
9 brevo_python.ApiClient(configuration)
10)
11account = api_instance.get_account()

Resources

  • GitHub Repository
  • PyPI Package
  • API Reference
  • Support