Node SDK
The @thumela/node client is implemented in this repository. These examples describe its current interface. Public access and distribution instructions will be provided at launch; this page does not assume you can obtain a public API key today.
The client is ESM-only and requires Node.js 20 or newer. It uses the runtime’s fetch and has no runtime dependencies.
Send and retrieve
Once you have access to the package and an internally provisioned key:
import { Thumela } from '@thumela/node';
const apiKey = process.env.THUMELA_API_KEY;
if (!apiKey) throw new Error('THUMELA_API_KEY is required');
const thumela = new Thumela(apiKey);
const { id } = await thumela.emails.send({
from: 'orders@example.test',
to: ['customer@example.test'],
subject: 'Your order is confirmed',
html: '<p>Thank you. Your order is confirmed.</p>',
text: 'Thank you. Your order is confirmed.',
idempotencyKey: 'order-1042-confirmed',
});
const message = await thumela.emails.get(id);Replace the .test addresses with a sender on your verified domain and an authorised recipient. Keep the key and all recipient data on your server.
Client options
const thumela = new Thumela(apiKey, {
baseUrl: 'https://api.thumela.co.za',
timeoutMs: 30_000,
fetch: globalThis.fetch,
});These are the defaults. You may supply a custom fetch or a different base URL for a local development API. The client does not automatically retry requests.
Handle errors
import { ThumelaError } from '@thumela/node';
try {
await thumela.emails.send(messageInput);
} catch (error) {
if (error instanceof ThumelaError) {
// statusCode is 0 for transport errors; code is the API error name.
// Handle the error without logging keys, message bodies or addresses.
if (error.code === 'Suppressed') {
// Stop attempts to send to this recipient.
}
}
throw error;
}ThumelaError exposes statusCode, code, message and body. A timeout or failed connection has code: 'NetworkError' and body: null.
React Email
Render your React Email component to HTML on the server, then pass that HTML to emails.send. The API and SDK accept html and text; they do not accept a React component or a react field.

