Node.js SDK

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

Overview

The Brevo Node.js SDK provides a TypeScript-first client library for interacting with the Brevo API. It offers type-safe methods, automatic retries, and comprehensive error handling.

Version 4.0 npm downloads

Version 4.0 of the Node.js SDK has been released with significant improvements:

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 projects and existing applications.

  • Promise-based API with async/await support
  • Enhanced TypeScript types and autocomplete
  • Standardized error handling with specific error types
  • Improved retry logic with exponential backoff
  • Better timeout configuration
  • Support for custom fetch implementations
  • Binary response handling

Installation

Install the SDK using npm:

$npm install @getbrevo/brevo@^4.0.1

Quick start

Initialize the client and send your first email:

quick-start.ts
1import { BrevoClient } from '@getbrevo/brevo';
2
3const brevo = new BrevoClient({
4 apiKey: 'your-api-key',
5});
6
7const result = await brevo.transactionalEmails.sendTransacEmail({
8 subject: "Hello",
9 textContent: "Hello world!",
10 sender: { name: "Sender", email: "sender@brevo.com" },
11 to: [{ email: "recipient@example.com" }]
12});
13
14console.log('Email sent:', result);

Configuration

Configure the client with custom timeout and retry settings:

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

Error handling

The SDK throws specific error types based on HTTP status codes. Handle errors appropriately:

error-handling.ts
1import {
2 BrevoError,
3 UnauthorizedError,
4 TooManyRequestsError
5} from '@getbrevo/brevo';
6
7try {
8 await brevo.transactionalEmails.sendTransacEmail({
9 subject: "Hello",
10 textContent: "Hello world!",
11 sender: { name: "Sender", email: "sender@brevo.com" },
12 to: [{ email: "recipient@example.com" }]
13 });
14} catch (err) {
15 if (err instanceof UnauthorizedError) {
16 console.error('Invalid API key');
17 } else if (err instanceof TooManyRequestsError) {
18 const retryAfter = err.rawResponse.headers['retry-after'];
19 console.error(`Rate limited. Retry after ${retryAfter} seconds`);
20 } else if (err instanceof BrevoError) {
21 console.error(`API Error ${err.statusCode}:`, err.message);
22 }
23}

Error types

The SDK provides the following error types:

  • 400 - BadRequestError
  • 401 - UnauthorizedError
  • 403 - ForbiddenError
  • 404 - NotFoundError
  • 422 - UnprocessableEntityError
  • 429 - TooManyRequestsError
  • 500+ - InternalServerError

All BrevoError instances provide:

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

Retries

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

retries.ts
1// Client-level configuration
2const brevo = new BrevoClient({
3 apiKey: 'your-api-key',
4 maxRetries: 3
5});
6
7// Request-level configuration
8await brevo.transactionalEmails.sendTransacEmail({
9 subject: "Hello",
10 textContent: "Hello world!",
11 sender: { name: "Sender", email: "sender@brevo.com" },
12 to: [{ email: "recipient@example.com" }]
13}, {
14 maxRetries: 5
15});

Retry behavior

  • Retryable status codes: 408, 429, 500, 502, 503, 504
  • Exponential backoff: ~1s, ~2s, ~4s (with jitter)
  • Respects Retry-After header for rate limits
  • Can be disabled per request with maxRetries: 0

Timeouts

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

timeouts.ts
1// Client-level timeout
2const brevo = new BrevoClient({
3 apiKey: 'your-api-key',
4 timeoutInSeconds: 30
5});
6
7// Request-level timeout
8await brevo.transactionalEmails.sendTransacEmail({
9 subject: "Hello",
10 textContent: "Hello world!",
11 sender: { name: "Sender", email: "sender@brevo.com" },
12 to: [{ email: "recipient@example.com" }]
13}, {
14 timeoutInSeconds: 10
15});
  • Standard API calls: 30-60s (default)
  • Quick operations: 10-15s
  • Bulk operations: 120-300s
  • Real-time: 5-10s

Request options

Additional headers

Add custom headers to requests:

custom-headers.ts
1await brevo.transactionalEmails.sendTransacEmail({
2 subject: "Hello",
3 textContent: "Hello world!",
4 sender: { name: "Sender", email: "sender@brevo.com" },
5 to: [{ email: "recipient@example.com" }]
6}, {
7 headers: {
8 'X-Custom-Header': 'custom-value'
9 }
10});

Query parameters

Add query parameters to requests:

query-params.ts
1await brevo.transactionalEmails.sendTransacEmail({
2 subject: "Hello",
3 textContent: "Hello world!",
4 sender: { name: "Sender", email: "sender@brevo.com" },
5 to: [{ email: "recipient@example.com" }]
6}, {
7 queryParams: {
8 'customParam': 'value'
9 }
10});

Abort signal

Cancel requests using AbortController:

abort-signal.ts
1const controller = new AbortController();
2
3await brevo.transactionalEmails.sendTransacEmail({
4 subject: "Hello",
5 textContent: "Hello world!",
6 sender: { name: "Sender", email: "sender@brevo.com" },
7 to: [{ email: "recipient@example.com" }]
8}, {
9 abortSignal: controller.signal
10});
11
12// Cancel the request
13controller.abort();

Raw response

Access raw response headers and metadata:

raw-response.ts
1const { data, rawResponse } = await brevo.transactionalEmails.sendTransacEmail({
2 subject: "Hello",
3 textContent: "Hello world!",
4 sender: { name: "Sender", email: "sender@brevo.com" },
5 to: [{ email: "recipient@example.com" }]
6}).withRawResponse();
7
8console.log(rawResponse.headers['X-My-Header']);

Binary responses

Handle binary responses from endpoints like attachment downloads:

binary-responses.ts
1const response = await brevo.inboundParsing.getInboundEmailAttachment(
2 attachmentId,
3 downloadToken
4);
5
6// Choose one:
7const stream = response.stream();
8// const arrayBuffer = await response.arrayBuffer();
9// const blob = await response.blob();
10// const bytes = await response.bytes();

Saving binary responses

Save binary responses to a file in Node.js:

1import { createWriteStream } from 'fs';
2import { Readable } from 'stream';
3import { pipeline } from 'stream/promises';
4
5const stream = response.stream();
6const nodeStream = Readable.fromWeb(stream);
7await pipeline(nodeStream, createWriteStream('path/to/file'));

Save binary responses to a file in Bun:

1await Bun.write('path/to/file', response.stream());

Download binary responses in the browser:

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 for use in your application:

typescript-types.ts
1import { 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 debug API calls:

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 silent: false
9 }
10});

Custom logger

Implement a custom logger using your preferred logging library:

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

Custom fetch client

Override the default fetch implementation for advanced use cases:

custom-fetch.ts
1const customFetcher = async (
2 url: string,
3 options?: RequestInit
4): Promise<Response> => {
5 // Your custom implementation
6 return fetch(url, options);
7};
8
9const brevo = new BrevoClient({
10 apiKey: 'your-api-key',
11 fetcher: customFetcher
12});

Common use cases

Use node-fetch as the fetch implementation:

1import fetch from 'node-fetch';
2
3const brevo = new BrevoClient({
4 apiKey: 'your-api-key',
5 fetcher: fetch as any
6});

Use undici’s fetch implementation:

1import { fetch } from 'undici';
2
3const brevo = new BrevoClient({
4 apiKey: 'your-api-key',
5 fetcher: fetch as any
6});

Add request interceptors for custom headers or logging:

1const createFetcherWithInterceptors = () => {
2 return async (url: string, options?: RequestInit): Promise<Response> => {
3 const modifiedOptions = {
4 ...options,
5 headers: {
6 ...options?.headers,
7 'X-Request-ID': generateRequestId()
8 }
9 };
10 const response = await fetch(url, modifiedOptions);
11 console.log('Response:', response.status);
12 return response;
13 };
14};
15
16const brevo = new BrevoClient({
17 apiKey: 'your-api-key',
18 fetcher: createFetcherWithInterceptors()
19});

Runtime compatibility

The SDK is compatible with:

  • Node.js 18+
  • Vercel
  • Cloudflare Workers
  • Deno v1.25+
  • Bun 1.0+
  • React Native

Migration from v3.x

Version 4.0.1 includes breaking changes. Follow this guide to migrate from v3.x:

Key changes

  • New client initialization
  • Promise-based API
  • Improved TypeScript support
  • Standardized error handling

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