postject-sdk
v1.0.1
Published
Official Node.js SDK for Postject email API
Maintainers
Readme
Postject Node.js SDK
Official Node.js SDK for the Postject email API.
Installation
npm install postject-sdk
# or
yarn add postject-sdk
# or
pnpm add postject-sdkQuick Start
import { Postject } from 'postject-sdk';
const client = new Postject({
apiKey: 'pk_live_your_api_key_here',
});
// Send a simple email
await client.send({
to: '[email protected]',
subject: 'Welcome to our platform!',
html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
});Configuration
const client = new Postject({
apiKey: 'pk_live_your_api_key_here',
baseUrl: 'https://api.postject.com', // optional, defaults to production
timeout: 30000, // optional, request timeout in ms (default: 30000)
retries: 3, // optional, number of retries for rate limits (default: 3)
});Sending Emails
Simple Email
const result = await client.send({
to: '[email protected]',
from: '[email protected]', // optional if identity is configured
subject: 'Hello World',
html: '<p>This is a test email</p>',
text: 'This is a test email', // optional plain text version
});
console.log(result.id); // Message ID
console.log(result.status); // 'queued' | 'sent' | 'delivered' | 'bounced'Multiple Recipients
await client.send({
to: ['[email protected]', '[email protected]', '[email protected]'],
subject: 'Bulk announcement',
html: '<p>Important update for all users</p>',
});Using Templates
// Send using a pre-created template
await client.sendWithTemplate(
'template_id_here',
'[email protected]',
{
name: 'John Doe',
orderNumber: '12345',
orderTotal: '$99.00',
},
{
streamId: 'transactional_stream_id', // optional
}
);With Metadata and Tags
await client.send({
to: '[email protected]',
subject: 'Order Confirmation',
html: '<p>Your order has been confirmed</p>',
tags: ['order', 'confirmation'],
metadata: {
orderId: '12345',
customerId: 'cust_67890',
},
idempotencyKey: 'order_12345_confirmation', // prevents duplicate sends
});Content Analysis (Spam Check)
await client.send({
to: '[email protected]',
subject: 'Test Email',
html: '<p>Email content</p>',
analyzeContent: true, // automatically checks spam score
});Managing Resources
Servers
// List all servers
const servers = await client.getServers();
// Create a new server
const server = await client.createServer('Production Server');
// Delete a server
await client.deleteServer('server_id');Message Streams
// List streams
const streams = await client.getStreams('server_id');
// Create a stream
const stream = await client.createStream('server_id', {
name: 'Transactional Emails',
slug: 'transactional',
description: 'Order confirmations, password resets, etc.',
type: 'transactional',
});
// Delete a stream
await client.deleteStream('server_id', 'stream_id');Templates
// List templates
const templates = await client.getTemplates('server_id');
// Create a template
const template = await client.createTemplate('server_id', {
name: 'Welcome Email',
subject: 'Welcome to {{company_name}}!',
html: `
<h1>Welcome {{user_name}}!</h1>
<p>Thanks for signing up.</p>
`,
});
// Update a template
await client.updateTemplate('server_id', 'template_id', {
subject: 'Updated subject',
html: '<p>Updated content</p>',
});
// Delete a template
await client.deleteTemplate('server_id', 'template_id');Webhooks
// Create a webhook
const webhook = await client.createWebhook(
'stream_id',
'https://yourapp.com/webhooks/postject',
['delivered', 'bounced', 'complained'] // or ['*'] for all events
);
console.log(webhook.secret); // Use this to verify webhook signatures
// List webhooks
const webhooks = await client.getWebhooks('stream_id');
// Get webhook delivery logs
const { logs, total } = await client.getWebhookLogs('webhook_id', {
limit: 50,
offset: 0,
});
// Test a webhook
await client.testWebhook('webhook_id');
// Delete a webhook
await client.deleteWebhook('stream_id', 'webhook_id');Message Tracking
// Get message details
const message = await client.getMessage('message_id');
console.log(message.status); // 'queued' | 'sent' | 'delivered' | 'bounced'
console.log(message.routeName); // Which route was used
console.log(message.latencyMs); // Delivery latency
// Get message events (full timeline)
const events = await client.getMessageEvents('message_id');
events.forEach((event) => {
console.log(event.type, event.timestamp);
// 'queued', 'sent', 'delivered', 'opened', 'clicked', 'bounced', etc.
});API Key Management
// List API keys
const keys = await client.getApiKeys();
// Create a new API key
const newKey = await client.createApiKey('Production Key', 365); // expires in 365 days
console.log(newKey.key); // SAVE THIS - it won't be shown again
// Revoke a key
await client.revokeApiKey('key_id');
// Rotate a key (revoke old, create new)
const rotatedKey = await client.rotateApiKey('old_key_id', 'New Production Key');
console.log(rotatedKey.key); // New keyContent Analysis
// Check spam score before sending
const analysis = await client.analyzeContent(
'Subject line here',
'<html><body>Email content</body></html>'
);
console.log(analysis.overallScore); // 0-100 (higher is better)
console.log(analysis.spamScore); // 0-100 (lower is better)
console.log(analysis.issues); // Array of problems found
console.log(analysis.recommendations); // How to improve
// Example output:
// {
// overallScore: 75,
// spamScore: 25,
// htmlScore: 85,
// linkScore: 90,
// issues: [
// {
// severity: 'medium',
// message: 'Subject contains "FREE" in all caps',
// suggestion: 'Use normal capitalization'
// }
// ],
// recommendations: [
// 'Remove excessive exclamation marks',
// 'Add more text content (image/text ratio is high)'
// ]
// }Analytics
// Get server overview
const analytics = await client.getServerAnalytics('server_id');
console.log(analytics.totalSent); // Total emails sent
console.log(analytics.deliveryRate); // 0-1 (e.g., 0.98 = 98%)
console.log(analytics.bounceRate); // 0-1 (e.g., 0.02 = 2%)
console.log(analytics.avgLatency); // Average delivery time in msError Handling
The SDK throws specific error types for different scenarios:
import {
PostjectError,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
ServerError,
} from 'postject-sdk';
try {
await client.send({ /* ... */ });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
console.error(`Limit resets at ${error.resetAt}`);
} else if (error instanceof ValidationError) {
console.error('Invalid request:', error.response);
} else if (error instanceof NotFoundError) {
console.error('Resource not found');
} else if (error instanceof ServerError) {
console.error('Server error:', error.statusCode);
} else if (error instanceof PostjectError) {
console.error('API error:', error.message);
}
}TypeScript Support
The SDK is written in TypeScript and provides full type definitions:
import type {
SendEmailRequest,
SendEmailResponse,
Server,
MessageStream,
Template,
Webhook,
Message,
Event,
} from 'postject-sdk';
const request: SendEmailRequest = {
to: '[email protected]',
subject: 'Hello',
html: '<p>World</p>',
};
const response: SendEmailResponse = await client.send(request);Rate Limiting
The SDK automatically handles rate limits:
- Retries requests when rate limited (up to
retriestimes) - Respects
Retry-Afterheaders - Throws
RateLimitErrorif all retries exhausted
const client = new Postject({
apiKey: 'your_key',
retries: 5, // Retry up to 5 times on rate limits
});Examples
See the examples directory for complete working examples:
Support
- Documentation: https://postject.com/docs/sdk
- Email: [email protected]
License
MIT
