brevo-apiBrevo API integration with managed OAuth. Email marketing, transactional emails, SMS, contacts, and CRM. Use this skill when users want to send emails, manage contacts, create campaigns, or work with Brevo lists and templates. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
Install via ClawdBot CLI:
clawdbot install byungkyu/brevo-apiAccess the Brevo API with managed OAuth authentication. Send transactional emails, manage contacts and lists, create email campaigns, and work with templates.
# Get account info
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/brevo/v3/account')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://gateway.maton.ai/brevo/v3/{resource}
The gateway proxies requests to api.brevo.com and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Brevo OAuth connections at https://ctrl.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=brevo&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'brevo'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "b04dd695-d056-433b-baf9-0fb4eb3bde9e",
"status": "ACTIVE",
"creation_time": "2026-02-09T19:51:00.932629Z",
"last_updated_time": "2026-02-09T19:51:30.123456Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "brevo",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple Brevo connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/brevo/v3/account')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', 'b04dd695-d056-433b-baf9-0fb4eb3bde9e')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
GET /brevo/v3/account
Response:
{
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"companyName": "Acme Inc",
"relay": {
"enabled": true,
"data": {
"userName": "user@smtp-brevo.com",
"relay": "smtp-relay.brevo.com",
"port": 587
}
}
}
GET /brevo/v3/contacts
Query Parameters:
limit - Number of results per page (default: 50, max: 500)offset - Index of first result (0-based)modifiedSince - Filter by modification date (ISO 8601)Response:
{
"contacts": [
{
"id": 1,
"email": "contact@example.com",
"emailBlacklisted": false,
"smsBlacklisted": false,
"createdAt": "2026-02-09T20:33:59.705+01:00",
"modifiedAt": "2026-02-09T20:35:19.529+01:00",
"listIds": [2],
"attributes": {
"FIRSTNAME": "John",
"LASTNAME": "Doe"
}
}
],
"count": 1
}
GET /brevo/v3/contacts/{identifier}
The identifier can be email address, phone number, or contact ID.
Query Parameters:
identifierType - Type of identifier: email_id, phone_id, contact_id, ext_idPOST /brevo/v3/contacts
Content-Type: application/json
{
"email": "newcontact@example.com",
"attributes": {
"FIRSTNAME": "Jane",
"LASTNAME": "Smith"
},
"listIds": [2],
"updateEnabled": false
}
Response:
{
"id": 2
}
Set updateEnabled: true to update the contact if it already exists.
PUT /brevo/v3/contacts/{identifier}
Content-Type: application/json
{
"attributes": {
"FIRSTNAME": "Updated",
"LASTNAME": "Name"
}
}
Returns 204 No Content on success.
DELETE /brevo/v3/contacts/{identifier}
Returns 204 No Content on success.
GET /brevo/v3/contacts/{identifier}/campaignStats
GET /brevo/v3/contacts/lists
Response:
{
"lists": [
{
"id": 2,
"name": "Newsletter Subscribers",
"folderId": 1,
"uniqueSubscribers": 150,
"totalBlacklisted": 2,
"totalSubscribers": 148
}
],
"count": 1
}
GET /brevo/v3/contacts/lists/{listId}
POST /brevo/v3/contacts/lists
Content-Type: application/json
{
"name": "New List",
"folderId": 1
}
Response:
{
"id": 3
}
PUT /brevo/v3/contacts/lists/{listId}
Content-Type: application/json
{
"name": "Updated List Name"
}
Returns 204 No Content on success.
DELETE /brevo/v3/contacts/lists/{listId}
Returns 204 No Content on success.
GET /brevo/v3/contacts/lists/{listId}/contacts
POST /brevo/v3/contacts/lists/{listId}/contacts/add
Content-Type: application/json
{
"emails": ["contact1@example.com", "contact2@example.com"]
}
POST /brevo/v3/contacts/lists/{listId}/contacts/remove
Content-Type: application/json
{
"emails": ["contact1@example.com"]
}
GET /brevo/v3/contacts/folders
Response:
{
"folders": [
{
"id": 1,
"name": "Marketing",
"uniqueSubscribers": 500,
"totalSubscribers": 480,
"totalBlacklisted": 20
}
],
"count": 1
}
GET /brevo/v3/contacts/folders/{folderId}
POST /brevo/v3/contacts/folders
Content-Type: application/json
{
"name": "New Folder"
}
Response:
{
"id": 4
}
PUT /brevo/v3/contacts/folders/{folderId}
Content-Type: application/json
{
"name": "Renamed Folder"
}
Returns 204 No Content on success.
DELETE /brevo/v3/contacts/folders/{folderId}
Deletes folder and all lists within it. Returns 204 No Content on success.
GET /brevo/v3/contacts/folders/{folderId}/lists
GET /brevo/v3/contacts/attributes
Response:
{
"attributes": [
{
"name": "FIRSTNAME",
"category": "normal",
"type": "text"
},
{
"name": "LASTNAME",
"category": "normal",
"type": "text"
}
]
}
POST /brevo/v3/contacts/attributes/{category}/{attributeName}
Content-Type: application/json
{
"type": "text"
}
Categories: normal, transactional, category, calculated, global
PUT /brevo/v3/contacts/attributes/{category}/{attributeName}
Content-Type: application/json
{
"value": "new value"
}
DELETE /brevo/v3/contacts/attributes/{category}/{attributeName}
POST /brevo/v3/smtp/email
Content-Type: application/json
{
"sender": {
"name": "John Doe",
"email": "john@example.com"
},
"to": [
{
"email": "recipient@example.com",
"name": "Jane Smith"
}
],
"subject": "Welcome!",
"htmlContent": "<html><body><h1>Hello!</h1><p>Welcome to our service.</p></body></html>"
}
Response:
{
"messageId": "<202602092329.12910305853@smtp-relay.mailin.fr>"
}
Optional Parameters:
cc - Carbon copy recipientsbcc - Blind carbon copy recipientsreplyTo - Reply-to addresstextContent - Plain text versiontemplateId - Use a template instead of htmlContentparams - Template parametersattachment - File attachmentsheaders - Custom headerstags - Email tags for trackingscheduledAt - Schedule for later (ISO 8601)GET /brevo/v3/smtp/emails
Query Parameters:
email - Filter by recipient emailtemplateId - Filter by templatemessageId - Filter by message IDstartDate - Start date (YYYY-MM-DD)endDate - End date (YYYY-MM-DD)limit - Results per pageoffset - Starting indexDELETE /brevo/v3/smtp/email/{identifier}
The identifier can be a messageId or batchId.
GET /brevo/v3/smtp/statistics/events
Query Parameters:
limit - Results per pageoffset - Starting indexstartDate - Start dateendDate - End dateemail - Filter by recipientevent - Filter by event type: delivered, opened, clicked, bounced, etc.GET /brevo/v3/smtp/templates
Response:
{
"count": 1,
"templates": [
{
"id": 1,
"name": "Welcome Email",
"subject": "Welcome {{params.name}}!",
"isActive": true,
"sender": {
"name": "Company",
"email": "noreply@company.com"
},
"htmlContent": "<html>...</html>",
"createdAt": "2026-02-09 23:29:38",
"modifiedAt": "2026-02-09 23:29:38"
}
]
}
GET /brevo/v3/smtp/templates/{templateId}
POST /brevo/v3/smtp/templates
Content-Type: application/json
{
"sender": {
"name": "Company",
"email": "noreply@company.com"
},
"templateName": "Welcome Email",
"subject": "Welcome {{params.name}}!",
"htmlContent": "<html><body><h1>Hello {{params.name}}!</h1></body></html>"
}
Response:
{
"id": 1
}
PUT /brevo/v3/smtp/templates/{templateId}
Content-Type: application/json
{
"templateName": "Updated Template Name",
"subject": "New Subject"
}
Returns 204 No Content on success.
DELETE /brevo/v3/smtp/templates/{templateId}
Returns 204 No Content on success.
POST /brevo/v3/smtp/templates/{templateId}/sendTest
Content-Type: application/json
{
"emailTo": ["test@example.com"]
}
GET /brevo/v3/emailCampaigns
Query Parameters:
type - Filter by type: classic, triggerstatus - Filter by status: draft, sent, archive, queued, suspended, in_processlimit - Results per pageoffset - Starting indexResponse:
{
"count": 1,
"campaigns": [
{
"id": 2,
"name": "Monthly Newsletter",
"subject": "Our March Update",
"type": "classic",
"status": "draft",
"sender": {
"name": "Company",
"email": "news@company.com"
},
"createdAt": "2026-02-09T23:29:39.000Z"
}
]
}
GET /brevo/v3/emailCampaigns/{campaignId}
POST /brevo/v3/emailCampaigns
Content-Type: application/json
{
"name": "March Newsletter",
"subject": "Our March Update",
"sender": {
"name": "Company",
"email": "news@company.com"
},
"htmlContent": "<html><body><h1>March News</h1></body></html>",
"recipients": {
"listIds": [2]
}
}
Response:
{
"id": 2
}
PUT /brevo/v3/emailCampaigns/{campaignId}
Content-Type: application/json
{
"name": "Updated Campaign Name",
"subject": "Updated Subject"
}
Returns 204 No Content on success.
DELETE /brevo/v3/emailCampaigns/{campaignId}
Returns 204 No Content on success.
POST /brevo/v3/emailCampaigns/{campaignId}/sendNow
POST /brevo/v3/emailCampaigns/{campaignId}/sendTest
Content-Type: application/json
{
"emailTo": ["test@example.com"]
}
PUT /brevo/v3/emailCampaigns/{campaignId}/status
Content-Type: application/json
{
"status": "suspended"
}
GET /brevo/v3/senders
Response:
{
"senders": [
{
"id": 1,
"name": "Company",
"email": "noreply@company.com",
"active": true,
"ips": []
}
]
}
GET /brevo/v3/senders/{senderId}
POST /brevo/v3/senders
Content-Type: application/json
{
"name": "Marketing",
"email": "marketing@company.com"
}
PUT /brevo/v3/senders/{senderId}
Content-Type: application/json
{
"name": "Updated Name"
}
DELETE /brevo/v3/senders/{senderId}
GET /brevo/v3/smtp/blockedContacts
DELETE /brevo/v3/smtp/blockedContacts/{email}
GET /brevo/v3/smtp/blockedDomains
POST /brevo/v3/smtp/blockedDomains
Content-Type: application/json
{
"domain": "spam-domain.com"
}
DELETE /brevo/v3/smtp/blockedDomains/{domain}
Brevo uses offset-based pagination:
GET /brevo/v3/contacts?limit=50&offset=0
Parameters:
limit - Number of results per page (varies by endpoint, typically max 500)offset - Starting index (0-based)Response includes count:
{
"contacts": [...],
"count": 150
}
To get the next page, increment offset by limit:
offset=0&limit=50offset=50&limit=50offset=100&limit=50const response = await fetch(
'https://gateway.maton.ai/brevo/v3/contacts',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
console.log(data.contacts);
import os
import requests
response = requests.get(
'https://gateway.maton.ai/brevo/v3/contacts',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
print(data['contacts'])
import os
import requests
response = requests.post(
'https://gateway.maton.ai/brevo/v3/smtp/email',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'sender': {'name': 'John', 'email': 'john@example.com'},
'to': [{'email': 'recipient@example.com', 'name': 'Jane'}],
'subject': 'Hello!',
'htmlContent': '<html><body><h1>Hi Jane!</h1></body></html>'
}
)
result = response.json()
print(f"Sent! Message ID: {result['messageId']}")
import os
import requests
headers = {
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
}
# Create contact
response = requests.post(
'https://gateway.maton.ai/brevo/v3/contacts',
headers=headers,
json={
'email': 'newuser@example.com',
'attributes': {'FIRSTNAME': 'New', 'LASTNAME': 'User'},
'listIds': [2]
}
)
contact = response.json()
print(f"Created contact ID: {contact['id']}")
/v3/ prefix in the path{{params.name}} syntaxjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|--------|---------|
| 400 | Missing Brevo connection or bad request |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Brevo API |
Rate limit headers in response:
x-sib-ratelimit-limit - Request limitx-sib-ratelimit-remaining - Remaining requestsx-sib-ratelimit-reset - Reset timeWhen you receive an "Invalid API key" error, ALWAYS follow these steps before concluding there is an issue:
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Generated Feb 24, 2026
An online retailer uses Brevo to automatically send order confirmations, shipping notifications, and delivery updates to customers after purchases. This ensures timely communication, reduces support inquiries, and enhances customer experience by keeping buyers informed throughout the fulfillment process.
A software-as-a-service company leverages Brevo to create and send targeted email campaigns to nurture leads, onboard new users, and announce product updates. They segment contacts based on user behavior and subscription tiers to personalize content and improve engagement rates.
An event management firm utilizes Brevo to handle registrations by collecting attendee details, sending confirmation emails, and distributing post-event surveys or materials. This streamlines communication, ensures accurate attendee tracking, and gathers feedback for future improvements.
A nonprofit organization employs Brevo to manage donor contacts, send personalized thank-you emails, and run fundraising campaigns with segmented lists based on donation history. This helps maintain donor relationships, increase retention, and drive recurring contributions through targeted outreach.
A real estate agency uses Brevo to capture leads from property listings, send automated follow-ups with market insights, and notify subscribers about new listings or price changes. This keeps potential buyers and sellers engaged, builds trust, and converts leads into clients more effectively.
Companies offer Brevo integration as part of a monthly or annual subscription plan, providing access to email marketing, CRM features, and analytics. Revenue is generated through tiered pricing based on contact volume or email sends, with upsells for advanced automation or SMS capabilities.
Marketing agencies use Brevo to manage client campaigns, charging fees for setup, strategy, and ongoing management. Revenue comes from retainer contracts or project-based pricing, leveraging Brevo's API to automate workflows and report on performance metrics for multiple clients.
E-commerce platforms integrate Brevo directly into their systems to offer built-in email marketing tools to merchants. Revenue is generated through transaction fees, premium add-ons, or bundled packages that include Brevo features, driving value by enhancing merchant sales and customer retention.
💬 Integration Tip
Start by setting up a single Brevo connection via the Maton control panel to test basic API calls like fetching account info, then expand to contact management and email sending as you become familiar with the authentication and endpoint structure.
Use the mcporter CLI to list, configure, auth, and call MCP servers/tools directly (HTTP or stdio), including ad-hoc servers, config edits, and CLI/type generation.
Connect to 100+ APIs (Google Workspace, Microsoft 365, GitHub, Notion, Slack, Airtable, HubSpot, etc.) with managed OAuth. Use this skill when users want to...
Build, debug, and deploy websites using HTML, CSS, JavaScript, and modern frameworks following production best practices.
YouTube Data API integration with managed OAuth. Search videos, manage playlists, access channel data, and interact with comments. Use this skill when users want to interact with YouTube. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Scaffold, test, document, and debug REST and GraphQL APIs. Use when the user needs to create API endpoints, write integration tests, generate OpenAPI specs, test with curl, mock APIs, or troubleshoot HTTP issues.
Search for jobs across LinkedIn, Indeed, Glassdoor, ZipRecruiter, Google Jobs, Bayt, Naukri, and BDJobs using the JobSpy MCP server.