Node.js SDK

Learn how to integrate the Brevo API into your Node.js and browser applications.

Overview

The Brevo Node.js SDK (@getbrevo/brevo) is a TypeScript-first client library for the Brevo API. It provides:

  • A unified BrevoClient with namespaced service clients
  • Full TypeScript types with IDE autocomplete
  • Promise-based async/await API
  • Automatic retries with exponential backoff
  • Custom fetch support for any runtime
  • Structured error handling with typed error classes

npm

Version 4.0 is a full rewrite and is not backwards compatible with the v3.x SDK. The legacy v3.x SDK (@getbrevo/brevo@^3.0.1) will continue to receive critical security updates but no new features. We recommend migrating to v4.x for new and existing projects.

Requirements

  • Node.js 18+
  • Also compatible with: Vercel, Cloudflare Workers, Deno v1.25+, Bun 1.0+, React Native

Installation

$npm install @getbrevo/brevo

Quick start

Initialize the client and send your first email:

quick-start.ts
1import { BrevoClient } from '@getbrevo/brevo';
2
3const brevo = new BrevoClient({ apiKey: 'your-api-key' });
4
5const result = await brevo.transactionalEmails.sendTransacEmail({
6 subject: 'Hello from Brevo!',
7 htmlContent: '<html><body><p>Hello,</p><p>This is my first transactional email.</p></body></html>',
8 sender: { name: 'Alex from Brevo', email: 'hello@brevo.com' },
9 to: [{ email: 'johndoe@example.com', name: 'John Doe' }],
10});
11
12console.log('Email sent. Message ID:', result.messageId);

Configuration

Pass options to the constructor to configure timeout, retries, and other settings:

configuration.ts
1const brevo = new BrevoClient({
2 apiKey: 'your-api-key',
3 timeoutInSeconds: 30,
4 maxRetries: 3,
5});

Constructor options

OptionTypeDefaultDescription
apiKeystringRequiredYour Brevo API key
timeoutInSecondsnumber60Default request timeout in seconds
maxRetriesnumber2Maximum retry attempts on retryable errors
baseUrlstringnullOverride the default API base URL
fetchtypeof fetchnullCustom fetch implementation
headersRecord<string, string>nullAdditional default headers sent with every request
loggingLogConfig | LoggernullLogging configuration

Error handling

The SDK throws typed error classes based on HTTP status codes:

error-handling.ts
1import {
2 BrevoError,
3 UnauthorizedError,
4 TooManyRequestsError,
5} from '@getbrevo/brevo';
6
7try {
8 await brevo.transactionalEmails.sendTransacEmail({ ... });
9} catch (err) {
10 if (err instanceof UnauthorizedError) {
11 console.error('Invalid API key');
12 } else if (err instanceof TooManyRequestsError) {
13 const retryAfter = err.rawResponse.headers['retry-after'];
14 console.error(`Rate limited. Retry after ${retryAfter}s`);
15 } else if (err instanceof BrevoError) {
16 console.error(`API error ${err.statusCode}:`, err.message);
17 }
18}

Error classes

Status codeClass
400BadRequestError
401UnauthorizedError
403ForbiddenError
404NotFoundError
422UnprocessableEntityError
429TooManyRequestsError
500+InternalServerError

All BrevoError instances expose:

  • statusCode — HTTP status code
  • message — Error message
  • body — Parsed response body
  • rawResponse — Raw response with headers

Retries

Automatic retries with exponential backoff are enabled by default (2 retries). Configure at the client or request level:

retries.ts
1// Client-level
2const brevo = new BrevoClient({
3 apiKey: 'your-api-key',
4 maxRetries: 3,
5});
6
7// Request-level (overrides client setting)
8await brevo.transactionalEmails.sendTransacEmail({ ... }, {
9 maxRetries: 0, // Disable retries for this request
10});

Retry behavior

  • Retryable status codes: 408, 429, 500, 502, 503, 504
  • Backoff schedule: ~1s, ~2s, ~4s (exponential with jitter)
  • Rate limit headers: Respects Retry-After response header

Timeouts

Default timeout is 60 seconds. Configure at the client or request level:

timeouts.ts
1// Client-level
2const brevo = new BrevoClient({
3 apiKey: 'your-api-key',
4 timeoutInSeconds: 30,
5});
6
7// Request-level (overrides client setting)
8await brevo.transactionalEmails.sendTransacEmail({ ... }, {
9 timeoutInSeconds: 10,
10});
Use caseTimeout
Standard API calls30–60s (default)
Quick operations10–15s
Bulk operations120–300s
Real-time / low-latency5–10s

Request options

All service methods accept a request options object as the final argument:

request-options.ts
1await brevo.transactionalEmails.sendTransacEmail({ ... }, {
2 timeoutInSeconds: 10,
3 maxRetries: 1,
4 headers: { 'X-Custom-Header': 'custom-value' },
5 queryParams: { customParam: 'value' },
6});

Abort signal

Cancel in-flight requests using the Web AbortController API:

abort-signal.ts
1const controller = new AbortController();
2
3await brevo.transactionalEmails.sendTransacEmail({ ... }, {
4 abortSignal: controller.signal,
5});
6
7controller.abort(); // Cancel the request

Raw response

Access response headers and metadata via .withRawResponse():

raw-response.ts
1const { data, rawResponse } = await brevo.transactionalEmails
2 .sendTransacEmail({ ... })
3 .withRawResponse();
4
5console.log(rawResponse.headers['x-request-id']);
6console.log(data.messageId);

Binary responses

Endpoints that return binary content (e.g., attachment downloads) expose multiple consumption methods:

binary-responses.ts
1const response = await brevo.inboundParsing.getInboundEmailAttachment(downloadToken);
2
3const stream = response.stream();
4const arrayBuffer = await response.arrayBuffer();
5const blob = await response.blob();
6const bytes = await response.bytes();

Saving binary content

1import { createWriteStream } from 'fs';
2import { Readable } from 'stream';
3import { pipeline } from 'stream/promises';
4
5const stream = response.stream();
6await pipeline(Readable.fromWeb(stream), createWriteStream('path/to/file'));
1await Bun.write('path/to/file', response.stream());
1const blob = await response.blob();
2const url = URL.createObjectURL(blob);
3const a = document.createElement('a');
4a.href = url;
5a.download = 'filename';
6a.click();
7URL.revokeObjectURL(url);

TypeScript types

All request and response types are exported from the package:

typescript-types.ts
1import type { Brevo } from '@getbrevo/brevo';
2
3const request: Brevo.SendTransacEmailRequest = {
4 subject: 'First email',
5 textContent: 'Hello world!',
6 sender: { name: 'Bob Wilson', email: 'bob.wilson@brevo.com' },
7 to: [{ email: 'sarah.davis@example.com', name: 'Sarah Davis' }],
8};

Logging

Configure logging to inspect outgoing requests and responses:

logging.ts
1import { BrevoClient, logging } from '@getbrevo/brevo';
2
3const brevo = new BrevoClient({
4 apiKey: 'your-api-key',
5 logging: {
6 level: logging.LogLevel.Debug,
7 logger: new logging.ConsoleLogger(),
8 },
9});

Custom logger

Integrate with any logging library by implementing the ILogger interface:

custom-logger.ts
1import winston from 'winston';
2import { logging } from '@getbrevo/brevo';
3
4const winstonLogger = winston.createLogger({
5 level: 'info',
6 format: winston.format.json(),
7 transports: [new winston.transports.Console()],
8});
9
10const logger: logging.ILogger = {
11 debug: (msg, ...args) => winstonLogger.debug(msg, ...args),
12 info: (msg, ...args) => winstonLogger.info(msg, ...args),
13 warn: (msg, ...args) => winstonLogger.warn(msg, ...args),
14 error: (msg, ...args) => winstonLogger.error(msg, ...args),
15};
16
17const brevo = new BrevoClient({
18 apiKey: 'your-api-key',
19 logging: { level: logging.LogLevel.Debug, logger },
20});

Custom fetch

Override the default fetch implementation for any runtime or to add request interceptors:

custom-fetch.ts
1const brevo = new BrevoClient({
2 apiKey: 'your-api-key',
3 fetch: async (url, options) => {
4 console.log('→', url);
5 const response = await fetch(url, options);
6 console.log('←', response.status);
7 return response;
8 },
9});

Common integrations

1import fetch from 'node-fetch';
2
3const brevo = new BrevoClient({
4 apiKey: 'your-api-key',
5 fetch: fetch as typeof globalThis.fetch,
6});
1import { fetch } from 'undici';
2
3const brevo = new BrevoClient({
4 apiKey: 'your-api-key',
5 fetch: fetch as typeof globalThis.fetch,
6});
1import { randomUUID } from 'crypto';
2
3const brevo = new BrevoClient({
4 apiKey: 'your-api-key',
5 fetch: async (url, options) => {
6 return fetch(url, {
7 ...options,
8 headers: {
9 ...options?.headers,
10 'X-Request-ID': randomUUID(),
11 },
12 });
13 },
14});

Available services

The BrevoClient exposes the following service namespaces:

PropertyDescription
transactionalEmailsSend emails, manage templates, blocked contacts and domains
transactionalSmsSend SMS messages and view delivery statistics
transactionalWhatsAppSend WhatsApp messages and view event reports
smsTemplatesManage SMS templates
contactsManage contacts, lists, folders, attributes and segments
emailCampaignsCreate and manage email marketing campaigns
smsCampaignsCreate and manage SMS marketing campaigns
whatsAppCampaignsCreate and manage WhatsApp campaigns and templates
companiesManage CRM companies
dealsManage CRM deals and pipelines
tasksManage CRM tasks
notesManage CRM notes
filesUpload and manage CRM files
conversationsManage conversation messages and automated messages
ecommerceManage products, categories, orders and attribution
couponsManage coupon collections and coupons
paymentsCreate and manage payment requests
eventTrack custom events
webhooksManage webhooks
sendersManage senders and IPs
domainsManage and authenticate domains
accountRetrieve account information and activity logs
inboundParsingRetrieve inbound email events and attachments
customObjectsManage custom object records
externalFeedsManage external RSS feeds
masterAccountManage sub-accounts and groups (enterprise)
userManage users and permissions
processRetrieve background process status
programManage loyalty programs
balanceManage loyalty balances and transactions
rewardManage loyalty rewards and vouchers
tierManage loyalty tiers and tier groups

Migration from v3.x

Key changes

Areav3.xv4.x
Clientnew TransactionalEmailsApi() per resourcenew BrevoClient({ apiKey }) unified
Auth(api as any).authentications.apiKey.apiKey = "..."Constructor option
API styleClass-based with settersPromise-based with inline objects
TypeScriptPartialFull, exported types
RetriesNot built-inAutomatic with exponential backoff

Migration example

1// v3.x
2import { TransactionalEmailsApi, SendSmtpEmail } from '@getbrevo/brevo';
3
4let emailAPI = new TransactionalEmailsApi();
5(emailAPI as any).authentications.apiKey.apiKey = 'xkeysib-xxx';
6
7let message = new SendSmtpEmail();
8message.subject = 'First email';
9message.textContent = 'Hello world!';
10message.sender = { name: 'Bob Wilson', email: 'bob.wilson@brevo.com' };
11message.to = [{ email: 'sarah.davis@example.com', name: 'Sarah Davis' }];
12
13emailAPI.sendTransacEmail(message);

Resources