DEV Community

Cover image for How to Use Brevo APIs for SMS Marketing ?
Wanda
Wanda

Posted on • Originally published at apidog.com

How to Use Brevo APIs for SMS Marketing ?

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.

Try Apidog today

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

  1. Log into Brevo
  2. Navigate to SMTP & API → API Keys
  3. Create a new API key with required permissions
  4. 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"
Enter fullscreen mode Exit fullscreen mode

API Base URL

All API endpoints are under:

https://api.brevo.com/v3/
Enter fullscreen mode Exit fullscreen mode

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."
  }'
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "messageId": "<20260324123456.123456@relay.brevo.com>"
}
Enter fullscreen mode Exit fullscreen mode

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"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
      }
    ]
  })
})
Enter fullscreen mode Exit fullscreen mode

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"
  }'
Enter fullscreen mode Exit fullscreen mode

Send Immediately

curl -X POST "https://api.brevo.com/v3/emailCampaigns/{campaignId}/sendNow" \
  -H "api-key: your-api-key"
Enter fullscreen mode Exit fullscreen mode

Get Campaign Statistics

curl -X GET "https://api.brevo.com/v3/emailCampaigns/{campaignId}" \
  -H "api-key: your-api-key"
Enter fullscreen mode Exit fullscreen mode

Example response:

{
  "statistics": {
    "delivered": 4850,
    "opened": 1455,
    "clicked": 291,
    "unsubscribed": 12,
    "bounces": 150
  }
}
Enter fullscreen mode Exit fullscreen mode

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
  }'
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"]
  }'
Enter fullscreen mode Exit fullscreen mode

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"]
  }'
Enter fullscreen mode Exit fullscreen mode

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
  }'
Enter fullscreen mode Exit fullscreen mode

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"
  }'
Enter fullscreen mode Exit fullscreen mode

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"
  }'
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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:

  • delivered
  • opened
  • clicked
  • bounced
  • spam
  • unsubscribed

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')
})
Enter fullscreen mode Exit fullscreen mode

Testing with Apidog

Thoroughly test email workflows—including templates, bounces, and webhooks—with Apidog.

Apidog Email Testing

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>/)
})
Enter fullscreen mode Exit fullscreen mode

Apidog Mock Response

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"
}
Enter fullscreen mode Exit fullscreen mode

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')
})
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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')
}
Enter fullscreen mode Exit fullscreen mode

404 Contact Not Found

Cause: Updating a non-existent contact.

Fix: Use updateEnabled: true when creating contacts:

{
  "email": "new@example.com",
  "updateEnabled": true
}
Enter fullscreen mode Exit fullscreen mode

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-key header
  • 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:

  1. Create a Brevo account and generate an API key
  2. Send your first transactional email
  3. Build a template in the Brevo visual editor
  4. Set up webhook handlers for bounces and unsubscribes
  5. 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>
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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)