senddy-node
v0.1.1
Published
Official Node.js/TypeScript SDK for Senddy
Maintainers
Readme
Senddy TypeScript SDK
Official TypeScript/JavaScript SDK for the Senddy email API.
Installation
Requires Node.js 18.13+.
npm install senddy-nodeQuick Start
import { Senddy } from 'senddy-node';
const senddy = new Senddy('sk_your_api_key');
// Send an email
const result = await senddy.emails.send({
from: '[email protected]',
to: '[email protected]',
subject: 'Hello',
html: '<p>Welcome!</p>',
});
console.log(result.id); // email_abc123Configuration
const client = new EmailClient('sk_your_api_key', {
baseUrl: 'https://api.senddy.io', // default: http://localhost:3012
timeout: 30_000, // ms, default: 30000
retries: 2, // default: 2
headers: { 'X-Custom': 'value' }, // extra headers on every request
});If no API key is passed, the SDK reads from the SENDDY_API_KEY environment variable.
Emails
Send
const result = await client.emails.send(
{
from: '[email protected]',
to: ['[email protected]', '[email protected]'],
subject: 'Hello',
html: '<p>Hi there</p>',
text: 'Hi there', // optional plain-text fallback
cc: '[email protected]', // optional
bcc: '[email protected]', // optional
reply_to: '[email protected]', // optional
tags: { campaign: 'welcome' }, // optional metadata
attachments: [
{
// optional
filename: 'report.pdf',
content: base64String,
content_type: 'application/pdf',
},
],
},
{
idempotencyKey: 'unique-key', // optional, prevents duplicate sends
},
);Get
const email = await client.emails.get('email_abc123');
console.log(email.status); // 'delivered'
console.log(email.recipients); // recipient details
console.log(email.events); // delivery eventsList
const { data, pagination } = await client.emails.list({
limit: 25,
offset: 0,
status: 'delivered',
since: '2026-01-01T00:00:00Z',
});Download EML
const { content, contentType } = await client.emails.download('email_abc123');
// content is a Buffer containing the raw EMLSuppressions
List
const { data, pagination } = await client.suppressions.list({
limit: 50,
search: 'example.com',
reason: 'hard_bounce',
});Create
const entry = await client.suppressions.create({
email_address: '[email protected]',
});Delete
const result = await client.suppressions.delete('[email protected]');
console.log(result.removed); // trueError Handling
import { ValidationError, RateLimitError, APIError } from 'senddy-node';
try {
await client.emails.send({
/* ... */
});
} catch (err) {
if (err instanceof ValidationError) {
console.error('Validation:', err.details);
} else if (err instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${err.retryAfter}s`);
} else if (err instanceof APIError) {
console.error(`API error ${err.statusCode}: ${err.message}`);
}
}Error Types
| Class | Status | Description |
| --------------------- | ------ | ------------------------------------------- |
| ValidationError | 400 | Invalid request, includes .details array |
| AuthenticationError | 401 | Missing or invalid API key |
| ForbiddenError | 403 | Insufficient permissions |
| NotFoundError | 404 | Resource not found |
| RateLimitError | 429 | Rate limit exceeded, includes .retryAfter |
| InternalError | 5xx | Server error |
Retries
The SDK automatically retries on 429 and 5xx responses with exponential backoff and jitter. Retries respect the Retry-After header. Non-retryable errors (4xx except 429) are thrown immediately.
Requirements
- Node.js >= 18.13.0
- Zero runtime dependencies (uses native
fetch)
License
MIT
