TL;DR
Brevo APIs allow you to programmatically send marketing emails, transactional emails, and SMS messages. Authenticate using an API key, make HTTP requests to api.brevo.com, and use webhooks to track delivery and engagement events. For robust integration and testing—including payload validation and webhook handler testing—use Apidog. Ensure your integration handles bounces and unsubscribes as expected.
Introduction
Brevo (formerly Sendinblue) is an email and SMS service provider trusted by over 500,000 businesses for marketing campaigns, transactional messages, SMS marketing, and automation.
While sending an email via API seems simple, real-world systems must manage bounces, spam complaints, unsubscribes, and delivery timing. Brevo abstracts this complexity.
The Brevo API covers:
- Marketing campaigns: Bulk emails to lists
- Transactional emails: Password resets, order confirmations, etc.
- SMS messages: Verification codes, alerts, marketing messages
💡 Tip: When integrating email/SMS features, Apidog helps you test templates, validate webhook payloads, and simulate Brevo’s responses without sending real emails.
Authentication and Setup
Get an API Key
- Log into Brevo
- Navigate to SMTP & API → API Keys
- Create a new API key with required permissions
- Store your API key securely
Use the key in the api-key HTTP header:
curl -X GET "https://api.brevo.com/v3/account" \
-H "accept: application/json" \
-H "api-key: your-api-key-here"
API Base URL
All API endpoints are under:
https://api.brevo.com/v3/
Rate Limits
Brevo rate limits based on your plan:
- Free: 300 requests/minute
- Starter: 600 requests/minute
- Business: 1200 requests/minute
Monitor the X-RateLimit-Remaining header to avoid hitting the limit.
Sending Transactional Emails
Transactional emails are individual messages triggered by user actions—such as password resets or order confirmations.
Send a Simple Email
curl -X POST "https://api.brevo.com/v3/smtp/email" \
-H "accept: application/json" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"sender": {
"name": "Your App",
"email": "noreply@yourapp.com"
},
"to": [
{
"email": "user@example.com",
"name": "John Doe"
}
],
"subject": "Welcome to Our Platform",
"htmlContent": "<html><body><h1>Welcome!</h1><p>Thanks for signing up.</p></body></html>",
"textContent": "Welcome! Thanks for signing up."
}'
Response:
{
"messageId": "<20260324123456.123456@relay.brevo.com>"
}
Using Templates
Create reusable templates in the Brevo dashboard. Reference them by ID:
curl -X POST "https://api.brevo.com/v3/smtp/email" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"templateId": 15,
"to": [
{
"email": "user@example.com",
"name": "John Doe"
}
],
"params": {
"name": "John",
"order_number": "ORD-12345",
"tracking_url": "https://tracking.example.com/ORD-12345"
}
}'
Template variables use double braces:
<p>Hi {{params.name}},</p>
<p>Your order {{params.order_number}} has shipped.</p>
<p><a href="{{params.tracking_url}}">Track your package</a></p>
Send with Attachments
Example using JavaScript (Node.js):
const response = await fetch('https://api.brevo.com/v3/smtp/email', {
method: 'POST',
headers: {
'api-key': process.env.BREVO_API_KEY,
'content-type': 'application/json'
},
body: JSON.stringify({
sender: { name: 'Your App', email: 'noreply@yourapp.com' },
to: [{ email: 'user@example.com' }],
subject: 'Your Invoice',
htmlContent: '<p>Please find your invoice attached.</p>',
attachment: [
{
name: 'invoice.pdf',
content: base64EncodedPdfContent
}
]
})
})
Marketing Campaigns
Marketing emails are sent to contact lists. Brevo handles scheduling, analytics, and unsubscribe links.
Create a Campaign
curl -X POST "https://api.brevo.com/v3/emailCampaigns" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"name": "March Newsletter",
"subject": "What's New in March",
"sender": {
"name": "Your Brand",
"email": "newsletter@yourbrand.com"
},
"type": "classic",
"htmlContent": "<html><body>Newsletter content here...</body></html>",
"recipients": {
"listIds": [12, 15]
},
"scheduledAt": "2026-03-25T09:00:00+00:00"
}'
Send Immediately
curl -X POST "https://api.brevo.com/v3/emailCampaigns/{campaignId}/sendNow" \
-H "api-key: your-api-key"
Get Campaign Statistics
curl -X GET "https://api.brevo.com/v3/emailCampaigns/{campaignId}" \
-H "api-key: your-api-key"
Example response:
{
"statistics": {
"delivered": 4850,
"opened": 1455,
"clicked": 291,
"unsubscribed": 12,
"bounces": 150
}
}
Contact Management
Manage your audience by organizing contacts into lists and adding custom attributes.
Create a Contact
curl -X POST "https://api.brevo.com/v3/contacts" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"email": "new.user@example.com",
"attributes": {
"FIRSTNAME": "Jane",
"LASTNAME": "Smith",
"PLAN": "premium"
},
"listIds": [12, 15],
"updateEnabled": true
}'
Set updateEnabled: true to update existing contacts.
Get Contact Details
curl -X GET "https://api.brevo.com/v3/contacts/user@example.com" \
-H "api-key: your-api-key"
Add to List
curl -X POST "https://api.brevo.com/v3/contacts/lists/12/contacts/add" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"emails": ["user1@example.com", "user2@example.com"]
}'
Remove from List
curl -X DELETE "https://api.brevo.com/v3/contacts/lists/12/contacts/remove" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"emails": ["user@example.com"]
}'
Unsubscribe a Contact
curl -X PUT "https://api.brevo.com/v3/contacts/user@example.com" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"emailBlacklisted": true
}'
SMS Marketing
Brevo provides global SMS sending via API.
Send an SMS (Transactional)
curl -X POST "https://api.brevo.com/v3/transactionalSMS/sms" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"sender": "YourApp",
"recipient": "+15551234567",
"content": "Your verification code is: 123456",
"type": "transactional"
}'
Send Marketing SMS
curl -X POST "https://api.brevo.com/v3/transactionalSMS/sms" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"sender": "YourBrand",
"recipient": "+15551234567",
"content": "Flash sale! 50% off today only. Reply STOP to unsubscribe.",
"type": "marketing"
}'
Get SMS Statistics
curl -X GET "https://api.brevo.com/v3/transactionalSMS/statistics?startDate=2026-03-01&endDate=2026-03-31" \
-H "api-key: your-api-key"
Webhooks for Tracking
Webhooks enable your app to react to email/SMS events in real time.
Configure Webhooks
In the Brevo dashboard:
Settings → Webhooks → Add webhook
Track events such as:
deliveredopenedclickedbouncedspamunsubscribed
Handle Webhook Payload
Example (Node.js/Express):
app.post('/webhooks/brevo', (req, res) => {
const event = req.body
switch (event.event) {
case 'delivered':
console.log(`Email ${event.messageId} delivered to ${event.email}`)
break
case 'opened':
console.log(`Email opened by ${event.email} at ${event.date}`)
break
case 'bounced':
console.log(`Bounce: ${event.email} - ${event.reason}`)
markContactBounced(event.email)
break
case 'spam':
console.log(`Spam complaint from ${event.email}`)
removeFromAllLists(event.email)
break
case 'unsubscribed':
console.log(`Unsubscribed: ${event.email}`)
break
}
res.status(200).send('OK')
})
Testing with Apidog
Thoroughly test email workflows—including templates, bounces, and webhooks—with Apidog.
1. Mock Email Sending
Don’t send real emails during dev. Mock and validate responses:
pm.test('Email API accepts valid payload', () => {
const response = pm.response.json()
pm.expect(response).to.have.property('messageId')
pm.expect(response.messageId).to.match(/<.*@relay\.brevo\.com>/)
})
2. Test Webhook Handling
Create mock webhook payloads in Apidog:
{
"event": "bounced",
"email": "invalid@example.com",
"messageId": "<12345@relay.brevo.com>",
"reason": "hard_bounce",
"date": "2026-03-24T12:00:00Z",
"subject": "Welcome to Our Platform"
}
Send these to your webhook endpoint and verify your handler logic.
3. Validate Templates
Store sample payloads and check template variable replacement:
pm.test('Template variables are valid', () => {
const payload = pm.request.body.toJSON()
pm.expect(payload.params).to.have.property('name')
pm.expect(payload.params).to.have.property('order_number')
})
4. Environment Separation
Configure API keys for different environments:
# Development
BREVO_API_KEY: xkeysib-dev-xxx
BREVO_SENDER: dev@yourapp.com
# Production
BREVO_API_KEY: xkeysib-prod-xxx
BREVO_SENDER: noreply@yourapp.com
Test Brevo email APIs with Apidog for free.
Common Errors and Fixes
400 Bad Request - Missing Required Field
Cause: Missing required fields.
Fix: Review the error message.
{
"code": "invalid_parameter",
"message": "sender.email is required"
}
401 Unauthorized
Cause: Invalid or missing API key.
Fix: Check api-key header and ensure the key is valid.
402 Payment Required
Cause: Exceeded limits or insufficient credits.
Fix:
- For email: Review plan limits.
- For SMS: Purchase more SMS credits.
429 Too Many Requests
Cause: Rate limit exceeded.
Fix: Implement exponential backoff:
async function sendWithRetry(email, retries = 3) {
for (let i = 0; i < retries; i++) {
const response = await sendEmail(email)
if (response.status === 429) {
await sleep(Math.pow(2, i) * 1000)
} else {
return response
}
}
throw new Error('Rate limit exceeded')
}
404 Contact Not Found
Cause: Updating a non-existent contact.
Fix: Use updateEnabled: true when creating contacts:
{
"email": "new@example.com",
"updateEnabled": true
}
Creates or updates the contact as needed.
Alternatives and Comparisons
| Feature | Brevo | SendGrid | Mailchimp | Postmark |
|---|---|---|---|---|
| Pricing | 300 emails/day free | 100 emails/day free | 500 emails/month free | 100 emails/month free |
| Marketing emails | Yes | Yes | Yes | No |
| Transactional emails | Yes | Yes | Limited | Yes (specialized) |
| SMS | Yes | No | No | No |
| Automation | Yes | Yes | Yes | Limited |
| Template editor | Visual + code | Code | Visual | Code |
Brevo stands out with combined email and SMS support at competitive pricing.
Real-World Use Cases
- E-commerce order flow: Send transactional (order confirmation, shipping notification), marketing (abandoned cart, promotions) emails, and automate with one integration.
- SaaS onboarding: Deliver welcome emails, password resets, and team invitations via transactional API. Use marketing emails for feature announcements.
- SMS verification: Use the SMS API for two-factor authentication codes. Handle delivery failures via webhooks for retry logic.
Conclusion
Key takeaways:
- Brevo APIs cover marketing, transactional email, and SMS
- Authenticate via the
api-keyheader - Use templates for maintainable communications
- Manage contacts/lists for targeted messaging
- Leverage webhooks for delivery tracking and event handling
- Test thoroughly with Apidog
Next steps:
- Create a Brevo account and generate an API key
- Send your first transactional email
- Build a template in the Brevo visual editor
- Set up webhook handlers for bounces and unsubscribes
- Test your full flow with Apidog in development
Test Brevo email APIs with Apidog—free.
FAQ
What’s the difference between Brevo and Sendinblue?
Same product, new name. Sendinblue rebranded to Brevo in 2023. APIs use api.brevo.com but you may see "Sendinblue" in older docs.
How many emails can I send for free?
300 emails/day (9,000/month) on the free plan. Paid plans start at $25/month for 20,000 emails.
Can I use Brevo for cold emails?
Technically yes, but cold emailing risks high bounces and spam complaints. Brevo monitors sender reputation—high complaints can mean account suspension. Warm up your domain and follow best practices.
How do I handle email bounces?
Listen for bounced webhooks. Hard bounces (invalid email) should remove contacts. Soft bounces (temporary) can be retried. Monitor bounce rates—above 5% harms sender reputation.
What’s the difference between marketing and transactional emails?
Transactional: Sent to individuals after an action (purchase, signup).
Marketing: Sent to many recipients as part of a campaign. Brevo separates these for compliance and deliverability.
How do I add an unsubscribe link?
Brevo adds unsubscribe links to marketing emails automatically. For transactional emails, add your own:
<a href="{{ unsubscribe_url }}">Unsubscribe</a>
Can I send emails from my own domain?
Yes—set up SPF, DKIM, and DMARC in Brevo dashboard under Sender & IP. Without these, emails may be marked as spam.
How do I schedule emails in a specific timezone?
Use the scheduledAt field (ISO 8601):
{
"scheduledAt": "2026-03-25T09:00:00-05:00"
}
What happens if I hit the rate limit?
You'll get a 429 error. Check the X-RateLimit-Reset header for when to retry. Implement exponential backoff or queue messages for later processing.


Top comments (0)