Brevo runs one REST API at v3 on api.brevo.com, covering transactional email, contacts, campaigns, CRM objects, SMS, domains and webhooks from a single key. It is also one of very few ESPs with a first-party MCP server — a remote endpoint at mcp.brevo.com, live since October 14, 2025, exposing 27 modules. The trap is credential sprawl: Brevo issues an SMTP key, a v3 API key and an MCP token, and none substitutes for another.
Most platforms in this category still have no first-party Model Context Protocol surface, leaving buyers to choose between community wrappers and generic HTTP tool-calling. Brevo is the exception.
Brevo runs its own endpoint at https://mcp.brevo.com/v1/brevo/mcp, announced October 14, 2025, covering 27 modules: contacts, campaigns, CRM deals, companies and tasks, templates, SMS, WhatsApp, lists, segments, senders, domains and webhooks. It is remote HTTP, so nothing installs locally; auth is a dedicated MCP API token sent as Authorization: Bearer — not your v3 API key.
The first three are Brevo’s own documentation surfaces for the same hosted server; the last two are third-party.
Combined endpoint for all 27 modules, plus per-module endpoints at /v1/brevo_{module}/mcp. Clients: Claude Desktop, Claude Code, Cursor, Windsurf, VS Code, Cline.
Launch announcement dated October 14, 2025, covering campaign insights, contact management and pipeline data.
Setup walkthrough for the MCP API key, with the warning that matters: it is visible only at creation and never again.
Houtini Ltd server with 16+ tools across contacts, campaigns, analytics, transactional email and templates. Uses a standard v3 API key.
Brevo through Zapier’s MCP surface, with the same 12+ triggers and 12+ actions.
Agent access sits on a credential you can revoke alone — killing the MCP token does not stop production sending. Per-module endpoints scope what a model sees: /v1/brevo_contacts/mcp loads contact tools only, instead of all 27 modules flooding the tool list and degrading selection accuracy. And a hosted server puts maintenance on Brevo when the API moves — exactly where community wrappers rot. Against Postmark or MailerSend, that is a real differentiator.
One versioned base path for everything: no split marketing and transactional hosts, no per-region endpoint, no request signing — a plain header carries the key.
| Base URL | https://api.brevo.com/v3/ |
| Legacy host | api.sendinblue.com — retired, still in old tutorials |
| Auth header | api-key: <apiKey> RECOMMENDED |
| Response format | JSON on every endpoint |
| Pagination | limit + offset, zero-based. Page 2 at limit 50 is offset=50; defaults vary by endpoint. |
| Async operations | Bulk jobs return a process id — poll GET /v3/processes/{processId} |
| Rate-limit response | 429 Too Many Requests |
| Max message size | 20 MB total, body plus attachments |
| Template attachments | Under 4 MB per file |
| Recipients per transactional email | 99 (help centre, not the API reference) |
The model is broad rather than deep. /v3/smtp/email is the API-side twin of the relay covered on the SMTP settings tab — same account, same domain authentication, same 20 MB ceiling. Around it sit contacts and lists, campaigns, CRM objects, senders and domains, webhooks, inbound parse and Enterprise sub-accounts. Brevo prices on email volume rather than stored contacts, so contact endpoints are cheap commercially but expensive to use quickly.
The primary method. Create a key under Account › SMTP & API › API Keys and send it in the api-key header on every call — no bearer prefix, no HMAC, no timestamp. Validate with GET /v3/account: a health check that costs no send.
Publishing into the Brevo App Marketplace uses OAuth 2.0 rather than a static key, managed with the first-party Brevo CLI (brevo app create, upload, scaffold). The CLI reached v2.0.0 on July 2, 2026 with breaking changes from v1.1.1.
The MCP server rejects your v3 API key. It needs a separate MCP token, created in the same Account › SMTP & API area and sent as Authorization: Bearer <token>. Brevo shows it once at creation, with no retrieval screen after.
An SMTP key for smtp-relay.brevo.com, a v3 API key for api.brevo.com, an MCP token for mcp.brevo.com. Brevo’s SMTP documentation warns explicitly to use the SMTP key, not an API key, on the relay: a v3 key in an SMTP password field returns 535 5.7.8 Authentication failed. Relay detail is on the SMTP settings tab.
Limits are per endpoint, in requests per second, across three tiers: General, Advanced (Professional and Enterprise) and Extended (Enterprise only). The spread between endpoints matters far more than between tiers.
| Endpoint | General | Advanced | Extended |
|---|---|---|---|
| POST /v3/smtp/email | 1,000 RPS | 2,000 RPS | 6,000 RPS |
| POST /v3/transactionalSMS/send | 150 RPS | 200 RPS | 250 RPS |
| /v3/contacts/{…} | 10 RPS | 20 RPS | 60 RPS |
| POST /v3/events | 10 RPS | 20 RPS | 60 RPS |
| Inbound webhook events (account-wide) | 20 events/s | Not tiered | Not tiered |
Hourly, that is 3,600,000 sends on General — a number almost nobody reaches. Contacts, at 36,000 per hour, is 100x tighter and is the real ceiling: any sync looping contact by contact returns 429 long before sending is stressed. Use the asynchronous bulk import instead — submit the batch, take the process id, poll GET /v3/processes/{processId}. Account quotas apply independently of rate: 200 contact attributes, 300 lists (600 on Professional), 40 outbound and 20 inbound webhooks.
Seven clients plus a CLI live in the getbrevo organisation, all generated from the same v3 specification. Method coverage is consistent; maintenance cadence is not.
| Language | Package | Install | Repo |
|---|---|---|---|
| Python | brevo-python | pip install brevo-python | brevo-python |
| Node / TypeScript | @getbrevo/brevo | npm install @getbrevo/brevo | brevo-node |
| PHP | getbrevo/brevo-php | composer require getbrevo/brevo-php | brevo-php |
| Java | brevo-java | Maven or Gradle — see the README | brevo-java |
| C# / .NET | brevo-csharp | NuGet — see the README | brevo-csharp |
| Ruby | brevo-ruby | gem install brevo-ruby | brevo-ruby |
| Go | brevo-go | go get github.com/getbrevo/brevo-go | brevo-go |
| CLI (not an SDK) | brevo-cli | brew install getbrevo/tap/brevo | brevo-cli |
Python, Node and PHP were updated August 10, 2026, Java and C# on August 12, 2026, the CLI on August 19, 2026. Ruby has not moved since June 25, 2025, Go since February 7, 2025: not deprecated, but they will not carry newly shipped endpoints. Separately, brevo-python v5.x dropped the SibApiV3Sdk client for a Brevo(api_key=...) constructor with Pydantic models — not ready, pin brevo-python>=4,<5.
Brevo publishes no list of third-party clients, and seven official languages leave little room for one — community effort went into MCP wrappers instead. What registries still carry are Sendinblue-era packages under the old sib-api-v3-sdk naming: not forks, but the previous generation of the official clients.
The fifteen resources below cover what most integrations touch; full schemas sit in the Brevo API reference.
| Resource | Methods | Description |
|---|---|---|
| Transactional email/v3/smtp/email | POST | Send a transactional email: sender, subject, to and content, or templateId. |
| Account/v3/account | GET | Plan, credits and account details. The standard key validation call. |
| Account activity/v3/account/activity | GET | User activity logs, for audit trails on shared logins. |
| Contacts/v3/contacts | GET, POST | List or create contacts. Capped at 10 RPS on General. |
| Events/v3/events | POST | Track a custom event for automation triggers and segmentation. |
| Transactional SMS/v3/transactionalSMS/send | POST | Send a transactional SMS. Credit-based, priced apart from email. |
| Senders/v3/senders | GET, POST | List verified sending identities or create a sender. |
| Sender detail/v3/senders/{senderId} | PUT, DELETE | Update or delete an individual sender. |
| Dedicated IPs/v3/senders/ips | GET | List dedicated IPs. A dedicated IP is what triggers the SPF include. |
| Domains/v3/domains | GET, POST | List authenticated sending domains or register a new one. |
| Domain authentication/v3/domains/{domainName}/authenticate | PUT | Verify Brevo code, DKIM and DMARC — the API version of clicking Verify. |
| Webhooks/v3/webhooks | GET, POST | List or create webhooks; type selects marketing, transactional or inbound. |
| Webhook history/v3/webhooks/export | POST | Export historical events to reconcile endpoint downtime. |
| Background processes/v3/processes/{processId} | GET | Poll an async job. Bulk imports return a process id, not a result. |
| Inbound email events/v3/inbound/events | GET | List parsed inbound messages; attachments via a DownloadToken. |
Webhooks come in three types, all created through POST /v3/webhooks: transactional (Sent, Delivered, Opened, Clicked, Soft and Hard Bounce, Invalid Email, Deferred, Complaint, Unsubscribed, Blocked, Error), marketing for campaign events, and inbound carrying inboundEmailProcessed. Inbound parse is a full product, not a raw MIME dump: it splits the reply from the quoted thread and signature into ExtractedMarkdownMessage and ExtractedMarkdownSignature.
Run this first: a 200 confirms the credential type and the plan tier governing your limits.
curl -s https://api.brevo.com/v3/account -H "api-key: YOUR_V3_API_KEY" # 200 -> email, companyName, plan[] and relay status. # 401 -> wrong credential type (SMTP key or MCP token), or revoked. # 429 -> over the tier limit for this endpoint.
The brevo-python v5.x shape. On v4 the import path and client construction differ.
# pip install brevo-python (v5.x)
from brevo import Brevo
from brevo.transactional_emails import (
SendTransacEmailRequestSender,
SendTransacEmailRequestToItem,
)
client = Brevo(api_key="YOUR_API_KEY")
client.transactional_emails.send_transac_email(
sender=SendTransacEmailRequestSender(
email="hello@yourdomain.com", name="Alex from Brevo"),
to=[SendTransacEmailRequestToItem(
email="johndoe@example.com", name="John Doe")],
subject="Hello from Brevo!",
html_content="<p>Tracking code: {{params.trackingCode}}</p>",
params={"trackingCode": "JD01460000300002350000"},
)
# v5 replaced the legacy sib_api_v3_sdk / SibApiV3Sdk client.
# On v4? Pin it: pip install 'brevo-python>=4,<5'// npm install @getbrevo/brevo
import { BrevoClient } from '@getbrevo/brevo';
const brevo = new BrevoClient({ apiKey: process.env.BREVO_API_KEY });
const result = await brevo.transactionalEmails.sendTransacEmail({
sender: { name: 'Alex from Brevo', email: 'hello@yourdomain.com' },
to: [{ email: 'johndoe@example.com', name: 'John Doe' }],
subject: 'Hello',
textContent: 'Hello world!',
});
// Replaces the old SibApiV3Sdk.TransactionalEmailsApi pattern.Clients with HTTP transport take the URL and Bearer header directly; stdio-only ones bridge via mcp-remote. Scope to one module unless you need all 27.
{
"mcpServers": {
"brevo-contacts": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.brevo.com/v1/brevo_contacts/mcp",
"--header", "Authorization: Bearer YOUR_MCP_API_TOKEN"
]
}
}
}
# All 27 modules: https://mcp.brevo.com/v1/brevo/mcp
# Per module: https://mcp.brevo.com/v1/brevo_{module}/mcpA v3 key pasted into an SMTP password field yields 535 5.7.8 Authentication failed, which Brevo’s troubleshooting article blames generically on a wrong username or password, bad login format, extra spaces or a revoked key — nothing points at credential type. The MCP token adds a second trap: shown once at creation, never retrievable. And the SMTP username is the SMTP login in the dashboard, not necessarily the address you sign in with. Separately, new accounts return 450 Your SMTP account is not yet activated until the transactional platform is activated — correct credentials, blocked send. Both are relay-side; see SMTP settings.
Everyone quotes 1,000 RPS for POST /v3/smtp/email, but /v3/contacts/{...} and POST /v3/events are capped at 10 RPS on the same tier. A migration creating contacts one at a time hits 429 within seconds while the sending budget sits untouched. Use the async bulk import and poll GET /v3/processes/{processId}: a plan upgrade buys 6x, batching buys far more.
The rename moved the API host to api.brevo.com and the relay to smtp-relay.brevo.com, and packages became @getbrevo/brevo, brevo-python and getbrevo/brevo-php. Both major clients have had breaking rewrites since, yet most tutorials still show the old shapes. The exception that catches careful readers: inbound parse MX targets are genuinely still inbound1.sendinblue.com and inbound2.sendinblue.com, and must not be modernised.
The free tier is 300 emails per day and counts API and SMTP sends as well as campaigns. Overflow is queued, not rejected: Brevo holds up to 1,000 extra emails until the counter resets, so a password reset arrives hours late rather than never — harder to debug, because your logs show success. Per-message caps apply on every plan: 99 recipients, 20 MB total, 4 MB per template attachment. Paid plans start at $9 per month for 5,000 emails, priced on volume rather than stored contacts — the structural difference from Mailchimp.
brevo app upload replaces brevo app update and shows a diff before pushing, and brevo app scaffold recovers a project folder.contactPixelTrackingConsent for per-contact open-tracking consent. Email Campaigns gained UTM customisation for utm_campaign, utm_content and utm_term.Running API changes appear in the developer changelog, product news at brevo.com/releases. Nothing on v3 is marked for deprecation — the breaking changes of the last two years were client-side rewrites, not endpoint removals: a fair stability signal against SendGrid or Mailjet.
The base URL is https://api.brevo.com/v3/. Send your key in an api-key header — no bearer prefix, no signing. Create keys under Account › SMTP & API › API Keys and validate with GET /v3/account. If a tutorial points at api.sendinblue.com, only the host changed.
Yes — a first-party remote server at https://mcp.brevo.com/v1/brevo/mcp, announced October 14, 2025, exposing 27 modules across contacts, campaigns, CRM objects, templates, SMS, WhatsApp, senders, domains and webhooks. Per-module endpoints follow https://mcp.brevo.com/v1/brevo_{module}/mcp. Documented clients: Claude Desktop, Claude Code, Cursor, Windsurf, VS Code and Cline. Whether it is gated behind a paid plan is not stated in official docs.
Per endpoint, across three tiers. POST /v3/smtp/email: 1,000 requests/second on General (3,600,000 per hour), 2,000 on Advanced, 6,000 on Extended. POST /v3/transactionalSMS/send: 150 / 200 / 250 RPS. /v3/contacts/{...} and POST /v3/events: 10 / 20 / 60 RPS. Over the limit returns 429. No ceiling is published for the relay itself.
Install brevo-python or @getbrevo/brevo, construct the client with your v3 API key, call the send method. Python v5.x: Brevo(api_key=...) then client.transactional_emails.send_transac_email(...). Node: new BrevoClient({ apiKey }) then brevo.transactionalEmails.sendTransacEmail(...). The sib_api_v3_sdk and SibApiV3Sdk.TransactionalEmailsApi patterns are pre-rewrite. Snippets in Code examples.
Create a dedicated receiving subdomain such as reply.yourdomain.com, separate from your sending domain, and verify it. Add two MX records: MX 10 inbound1.sendinblue.com. and MX 20 inbound2.sendinblue.com. — those legacy hostnames are the current documented values. Then create a webhook of type inbound subscribed to inboundEmailProcessed. Parsed mail arrives as JSON with ExtractedMarkdownMessage and ExtractedMarkdownSignature.
Three hosts, three credentials, no interchangeability. The SMTP key is the password for smtp-relay.brevo.com on ports 587, 465 or 2525, paired with the SMTP login shown in the dashboard — see SMTP settings. The v3 API key goes in the api-key header for api.brevo.com. The MCP token goes in an Authorization: Bearer header for mcp.brevo.com and is shown only once. All three live under Account › SMTP & API.
This review follows our email infrastructure testing methodology. We disclose affiliate relationships in our editorial independence policy.