JSPM

@swiftmails/sdk

1.0.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q36746F
  • License MIT

Official SwiftMail Node.js SDK - Enterprise-grade transactional email service

Package Exports

  • @swiftmails/sdk
  • @swiftmails/sdk/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@swiftmails/sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

SwiftMail Node.js SDK

Official Node.js SDK for SwiftMail - A high-performance transactional email service.

npm version License: MIT

Features

  • Enterprise-Grade - Production-ready with advanced features
  • TypeScript Support - Full type definitions included
  • Idempotency - Prevent duplicate sends with automatic key generation
  • Circuit Breaker - Fault tolerance and graceful degradation
  • Rate Limiting - Client-side concurrency control
  • Observability Hooks - Monitor requests, responses, and errors
  • Sandbox Mode - Test without sending real emails
  • Automatic Retry - Exponential backoff with configurable limits
  • Advanced Validation - Email format, attachment size, payload limits
  • Webhook Verification - HMAC-SHA256 signature validation

Installation

npm install @swiftmails/sdk

Quick Start

const SwiftMail = require('@swiftmails/sdk');

const client = new SwiftMail('your-api-key');

// Send an email
await client.send({
  from: 'sender@yourdomain.com',
  to: 'recipient@example.com',
  subject: 'Hello from SwiftMail',
  html: '<h1>Welcome!</h1><p>This is a test email.</p>',
  text: 'Welcome! This is a test email.'
});

Configuration

const client = new SwiftMail('your-api-key', {
  // Basic config
  baseURL: 'https://api.swiftmail.com',
  timeout: 30000,
  maxRetries: 3,
  apiVersion: 'v1',
  
  // Enterprise features
  sandbox: false,                    // Enable sandbox mode
  debug: true,                       // Enable debug logging
  structuredLogs: true,              // JSON format logs
  
  // Observability hooks
  onRequest: (request) => {
    console.log('Request:', request);
  },
  onResponse: (response) => {
    console.log('Response:', response);
  },
  onError: (error) => {
    console.error('Error:', error);
  },
  
  // Circuit breaker
  failureThreshold: 0.5,             // Open circuit at 50% failure rate
  windowSize: 10,                    // Track last 10 requests
  cooldownTime: 30000,               // 30 seconds cooldown
  
  // Rate limiting
  maxConcurrentRequests: 5,          // Max 5 concurrent requests
  
  // Validation limits
  maxAttachmentSize: 10 * 1024 * 1024,  // 10MB per attachment
  maxPayloadSize: 20 * 1024 * 1024,     // 20MB total
  maxSubjectLength: 998,                 // RFC 2822 limit
});

API Reference

Send Email

const result = await client.send({
  from: 'sender@yourdomain.com',
  to: 'recipient@example.com',
  subject: 'Email Subject',
  html: '<p>HTML content</p>',
  text: 'Plain text content',
  replyTo: 'reply@yourdomain.com',        // Optional
  headers: { 'X-Custom': 'value' },       // Optional
  tags: ['welcome', 'onboarding'],        // Optional
  attachments: [{                         // Optional
    filename: 'document.pdf',
    content: 'base64-encoded-content',
    contentType: 'application/pdf'
  }],
  idempotencyKey: 'unique-key-123'        // Optional (auto-generated if not provided)
});

console.log(result.id);     // Email ID
console.log(result.status); // queued, processing, sent, failed

Send with Template

await client.sendTemplate({
  template: 'welcome-email',
  to: 'newuser@example.com',
  from: 'welcome@yourdomain.com',
  data: {
    name: 'John Doe',
    activationLink: 'https://app.example.com/activate/abc123'
  }
});

Send Bulk Emails

const emails = [
  {
    from: 'sender@yourdomain.com',
    to: 'user1@example.com',
    subject: 'Welcome',
    html: '<p>Welcome user 1!</p>'
  },
  {
    from: 'sender@yourdomain.com',
    to: 'user2@example.com',
    subject: 'Welcome',
    html: '<p>Welcome user 2!</p>'
  }
];

const result = await client.sendBulk(emails);
console.log(result.batchId);

Get Email Log

const email = await client.getEmail('email-log-id');

console.log(email.status);      // queued, processing, sent, failed
console.log(email.from);
console.log(email.to);
console.log(email.subject);
console.log(email.createdAt);
console.log(email.sentAt);
console.log(email.smtpResponse);

List Emails

const results = await client.listEmails({
  status: 'sent',
  to: 'recipient@example.com',
  page: 1,
  limit: 50
});

console.log(results.total);
results.emails.forEach(email => {
  console.log(`${email.to}: ${email.status}`);
});

Auto-Pagination

// Fetches all pages automatically
const allEmails = await client.listAllEmails({
  status: 'sent'
});

console.log(`Total: ${allEmails.length}`);

Domain Management

// Add domain
const domain = await client.addDomain({ domain: 'yourdomain.com' });

console.log('Add these DNS records:');
domain.dnsRecords.forEach(record => {
  console.log(`${record.type} ${record.name} ${record.value}`);
});

// Verify domain
const verification = await client.verifyDomain(domain.id);
console.log('Verified:', verification.verified);

// List domains
const domains = await client.listDomains();

Suppression List

// Add to suppression list
await client.suppressEmail('bounced@example.com', 'hard_bounce');

// List suppressions
const suppressions = await client.listSuppressions({ page: 1, limit: 50 });

// Remove from suppression list
await client.unsuppressEmail('bounced@example.com');

Webhook Verification

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-swiftmail-signature'];
  const payload = req.body;
  const secret = 'your-webhook-secret';
  
  if (client.verifyWebhook(signature, payload, secret)) {
    // Webhook is authentic
    console.log('Event:', payload.event);
    res.sendStatus(200);
  } else {
    // Invalid signature
    res.sendStatus(401);
  }
});

Enterprise Features

Idempotency

Prevent duplicate sends with idempotency keys:

// Auto-generated key (recommended)
await client.send({
  from: 'orders@shop.com',
  to: 'customer@example.com',
  subject: 'Order Confirmation',
  html: '<p>Your order has been confirmed</p>'
});

// Custom key (for critical operations)
await client.send({
  from: 'orders@shop.com',
  to: 'customer@example.com',
  subject: 'Order Confirmation',
  html: '<p>Your order has been confirmed</p>',
  idempotencyKey: `order-${orderId}-confirmation`
});

Circuit Breaker

Automatic fault tolerance:

// Check circuit state
console.log(client.getCircuitState()); // CLOSED, OPEN, or HALF_OPEN

// Circuit opens automatically when failure rate exceeds threshold
// Prevents cascading failures
// Auto-recovers after cooldown period

Rate Limiting

Control concurrent requests:

// Monitor queue
console.log('Queue size:', client.getQueueSize());
console.log('Running requests:', client.getRunningRequests());

// Requests are automatically queued when limit is reached
const promises = emails.map(email => client.send(email));
await Promise.all(promises); // Only 5 run concurrently (configurable)

Observability Hooks

Integrate with monitoring services:

const client = new SwiftMail('api-key', {
  onRequest: (request) => {
    // Send to DataDog, New Relic, etc.
    datadog.increment('swiftmail.request');
  },
  onResponse: (response) => {
    // Track successful requests
    datadog.increment('swiftmail.success');
  },
  onError: (error) => {
    // Send to Sentry, Rollbar, etc.
    sentry.captureException(error);
  }
});

Sandbox Mode

Test without sending real emails:

const testClient = new SwiftMail('api-key', {
  sandbox: true
});

const result = await testClient.send({
  from: 'test@example.com',
  to: 'user@example.com',
  subject: 'Test',
  html: '<p>This will NOT be sent</p>'
});

console.log(result);
// { id: 'mock_uuid', status: 'queued', sandbox: true }

Error Handling

try {
  await client.send({
    from: 'invalid-email',
    to: 'user@example.com',
    subject: 'Test',
    html: '<p>Test</p>'
  });
} catch (error) {
  console.log('Message:', error.message);
  console.log('Code:', error.code);           // INVALID_EMAIL, MISSING_FIELD, etc.
  console.log('Status:', error.status);       // HTTP status code
  console.log('Request ID:', error.requestId); // For support
  console.log('Retryable:', error.retryable); // true/false
  
  if (error.retryable) {
    // Can retry manually if needed
  }
}

Error Codes

Code Description Retryable
MISSING_API_KEY API key not provided No
MISSING_FIELD Required field missing No
INVALID_EMAIL Invalid email format No
INVALID_DOMAIN Invalid domain format No
MISSING_CONTENT No HTML/text/template No
SUBJECT_TOO_LONG Subject exceeds limit No
ATTACHMENT_TOO_LARGE Attachment too big No
PAYLOAD_TOO_LARGE Total payload too big No
CIRCUIT_OPEN Circuit breaker open Yes
TIMEOUT Request timeout Yes
NETWORK_ERROR Network connection error Yes
HTTP_5XX Server error Yes
HTTP_429 Rate limit exceeded Yes

TypeScript Support

Full TypeScript definitions included:

import SwiftMail, { SendEmailParams, SwiftMailOptions } from '@swiftmails/sdk';

const options: SwiftMailOptions = {
  debug: true,
  maxRetries: 3,
  onRequest: (request) => {
    console.log(request.method, request.url);
  }
};

const client = new SwiftMail('api-key', options);

const params: SendEmailParams = {
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Hello',
  html: '<p>Test</p>'
};

await client.send(params);

Best Practices

1. Use Idempotency for Critical Emails

// Order confirmations, payment receipts, etc.
await client.send({
  from: 'orders@shop.com',
  to: customer.email,
  subject: 'Order Confirmation',
  html: orderTemplate,
  idempotencyKey: `order-${orderId}`
});

2. Monitor with Observability Hooks

const client = new SwiftMail('api-key', {
  onError: (error) => {
    if (!error.retryable) {
      // Alert on non-retryable errors
      alerting.notify('SwiftMail error', error);
    }
  }
});

3. Use Circuit Breaker State

if (client.getCircuitState() === 'OPEN') {
  // Fallback: queue for later or use backup service
  await queueForLater(email);
} else {
  await client.send(email);
}

4. Validate Before Sending

// SDK validates automatically, but you can pre-validate
if (!email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
  throw new Error('Invalid email');
}

5. Use Sandbox for Testing

const client = new SwiftMail(
  process.env.SWIFTMAIL_API_KEY,
  {
    sandbox: process.env.NODE_ENV !== 'production'
  }
);

Support

License

MIT License - see LICENSE file for details.

Changelog

See CHANGELOG.md for version history.