// tech · api integration
TL;DR
You don’t need an extra Brevo user or the account password to show transactional email logs in your own backoffice. One API key, one endpoint (GET /v3/smtp/statistics/events), called from your backend, never from the browser.
The problem
I needed the transactional email logs from Brevo inside my own backoffice: delivered, opened, clicked, bounced. The catch: I didn’t want to invite another user to the account, and I didn’t want to share the account password.
You don’t need either. Brevo’s API authenticates with an API key, and the key is the only thing the integration needs.
What I tried
The endpoint returns unaggregated transactional email activity:
GET https://api.brevo.com/v3/smtp/statistics/events
My first request was wrong in three ways:
- Header named
BREVO_API_KEY. It must beapi-key. - Extra
Authorization: Basic ...header. Brevo doesn’t use it here. Remove it. - Mixing
dayswithstartDate/endDate. They are not compatible.
What actually worked
Authentication
Generate the key in your Brevo account settings (SMTP & API) and send it in the api-key header:
$ curl --location 'https://api.brevo.com/v3/smtp/statistics/events' \
--header 'accept: application/json' \
--header 'api-key: <YOUR_API_KEY>'
Filtering by date
Two options, never both:
# Option 1: explicit range (startDate and endDate go together)
$ curl --location 'https://api.brevo.com/v3/smtp/statistics/events?startDate=2026-05-01&endDate=2026-06-18' \
--header 'accept: application/json' \
--header 'api-key: <YOUR_API_KEY>'
# Option 2: last N days, including today
$ curl --location 'https://api.brevo.com/v3/smtp/statistics/events?days=7' \
--header 'accept: application/json' \
--header 'api-key: <YOUR_API_KEY>'
Rules from the docs:
- Without
startDate/endDateordays, the default is the last 30 days. - The date range can’t exceed 90 days.
startDateis mandatory ifendDateis used, and vice versa. Format:YYYY-MM-DD.
Keep the key out of the browser
Never call Brevo from the frontend. The key would be exposed to anyone who opens DevTools.
backoffice frontend --> your backend API --> Brevo API
(api-key in env var)
- Store the key as an environment variable in the backend (in my case, Render).
- Expose your own endpoint, e.g.
GET /admin/email-logs?days=7. - The backend calls Brevo and returns only the fields the frontend needs.
Need real time? Use webhooks
If you need logs in near real time, polling is the wrong tool. Brevo can POST events to a URL you define when they happen: sent, delivered, opened, clicked, soft/hard bounce, invalid email, deferred, complaint, unsubscribed, blocked, error.
Store them in your own database and query that from the backoffice.
If the key leaks, rotate it
If a key ever lands in a chat, a screenshot or a commit, regenerate it. Revoking and creating a new one takes a minute.
Key takeaways
- A Brevo API key is enough to read email events. No extra user, no shared password.
- The header is
api-key, noAuthorizationheader, anddaysnever goes withstartDate/endDate. - Call Brevo from your backend with the key in an env var, and expose only the fields the frontend needs.
- For near real time, switch from polling to webhooks and store events yourself.
References
- Brevo — Get all your transactional email activity
- Brevo — Send a transactional email and webhooks
- Brevo — Events API
12 Nov 2026 · #brevo #apis #webhooks #security
GLB_