@masters-union/outbound-sdk
v0.1.4
Published
Official Node.js SDK for the Outbound Email SaaS platform
Maintainers
Readme
outbound-sdk
Official Node.js SDK for the Outbound email platform.
Install
npm install outbound-sdkQuick Start
import { Outbound } from 'outbound-sdk';
// Single tenant — set API key once
const outbound = new Outbound({ apiKey: 'mu_outbound_...' });
const { jobId } = await outbound.email.send({
toEmail: '[email protected]',
fromEmail: '[email protected]',
emailSubject: 'Welcome!',
htmlBody: '<h1>Hello World</h1>',
});Multi-Tenant Usage
For applications that manage multiple tenants, create one client and pass the API key per call:
const outbound = new Outbound(); // no default apiKey
const tenantAKey = 'mu_outbound_tenant_a_...';
const tenantBKey = 'mu_outbound_tenant_b_...';
await outbound.email.send({ toEmail: '...', ... }, { apiKey: tenantAKey });
await outbound.email.send({ toEmail: '...', ... }, { apiKey: tenantBKey });A per-call apiKey always takes priority over the constructor default.
Send Bulk Emails
const result = await outbound.email.bulk({
fromEmail: '[email protected]',
emailSubject: 'Newsletter',
emails: [
{ toEmail: '[email protected]', htmlBody: '<h1>Hi Alice</h1>' },
{ toEmail: '[email protected]', htmlBody: '<h1>Hi Bob</h1>' },
],
});
// result.recipientCount, result.jobIdCheck Job Status
const status = await outbound.email.status('job-uuid');
// status.job, status.recipientsTemplates
// Create
const { template } = await outbound.templates.create({
name: 'welcome',
subject: 'Welcome {{firstName}}!',
htmlBody: '<h1>Hello {{firstName}}</h1>',
variables: ['firstName'],
});
// List
const { templates, total } = await outbound.templates.list({ status: 'active' });
// Send using template
const { jobId } = await outbound.templates.send({
templateId: template.id,
toEmail: '[email protected]',
fromEmail: '[email protected]',
variables: { firstName: 'John' },
});
// Bulk send using template
const bulk = await outbound.templates.bulkSend({
templateId: template.id,
fromEmail: '[email protected]',
recipients: [
{ toEmail: '[email protected]', variables: { firstName: 'Alice' } },
{ toEmail: '[email protected]', variables: { firstName: 'Bob' } },
],
});
// Preview
const preview = await outbound.templates.preview(template.id, {
variables: { firstName: 'John' },
});Suppressions
// Add
await outbound.suppressions.add({ email: '[email protected]', reason: 'manual' });
// List
const { suppressions } = await outbound.suppressions.list({ reason: 'bounce' });
// Remove
await outbound.suppressions.remove('[email protected]');Webhooks
// Create
const { webhook, secret } = await outbound.webhooks.create({
url: 'https://myapp.com/webhooks/outbound',
events: ['delivery', 'bounce', 'complaint'],
});
// Store `secret` securely for signature verification
// Verify incoming webhook
const isValid = Outbound.verifyWebhookSignature(rawBody, signatureHeader, secret);Dashboard
const dashboard = await outbound.dashboard.get();
// dashboard.last30Days.sent, dashboard.quota, etc.
const quota = await outbound.dashboard.quota();
// quota.dailyUsed, quota.monthlyUsed, quota.remainingConfiguration
| Option | Default | Description |
|--------|---------|-------------|
| apiKey | — | Default API key (optional if provided per call) |
| baseUrl | https://outbound-api.mastersunion.org | API base URL |
| timeout | 30000 | Request timeout in ms |
| maxRetries | 3 | Max retries on 429/5xx |
| retryDelay | 1000 | Initial retry delay in ms (exponential backoff) |
Error Handling
All errors extend OutboundError with statusCode, message, and details:
import { Outbound, RateLimitError, NotFoundError } from 'outbound-sdk';
try {
await outbound.email.send({ ... });
} catch (err) {
if (err instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${err.retryAfter}s`);
} else if (err instanceof NotFoundError) {
console.log('Resource not found');
}
}| Error Class | Status Code |
|------------|-------------|
| BadRequestError | 400 |
| AuthenticationError | 401 |
| ForbiddenError | 403 |
| NotFoundError | 404 |
| ConflictError | 409 |
| RateLimitError | 429 |
| ServerError | 5xx |
| TimeoutError | - |
| NetworkError | - |
Requirements
- Node.js 18+ (uses native
fetch)
License
MIT
