Install
npm install @ewyn/client
# or
pnpm add @ewyn/client
# or
yarn add @ewyn/clientRequirements: Node.js 18+ (the SDK uses native fetch) and TypeScript 5.0+ for the type-safe features.
Create a client
import { Ewyn } from '@ewyn/client';
const client = new Ewyn({
apiKey: process.env.EWYN_API_KEY!,
});Constructor options:
| Option | Type | Default | Notes |
|---|---|---|---|
| apiKey | string | required | Your workspace API key secret |
| templates | TemplateConfig | — | Template config for name-based, type-safe sending — see Type-safe templates |
| maxRetries | number | 3 | Maximum total attempts for retryable errors, including the first |
| timeout | number | 60000 | Request timeout in milliseconds |
| debug | boolean | false | Log requests/retries to stderr. Also enabled when env DEBUG contains ewyn |
Send an email
await client.send({
to: 'user@example.com',
subject: 'Welcome!',
templateId: 'template-version-uuid',
type: 'transactional',
variables: {
firstName: 'John',
lastName: 'Doe',
},
});Declare type on every send: 'transactional' for service email the recipient expects (receipts, confirmations, resets), which ignores marketing unsubscribes, or 'marketing', which honours them and may carry a topic slug. See Subscriptions and unsubscribe. The full option list lives in the send endpoint reference — the SDK mirrors it one-to-one.
Sender overrides
Emails default to your workspace's configured sender. Override per-send when needed:
await client.send({
to: 'user@example.com',
subject: 'Hello from a custom sender',
templateId: 'template-version-uuid',
type: 'marketing',
topic: 'product-updates',
from: 'noreply@yourdomain.com',
fromName: 'Your App',
replyTo: 'support@yourdomain.com',
});Attachments
Pass raw bytes, a base64 string, or an https URL Ewyn fetches for you. Buffers are base64-encoded automatically.
import { readFile } from 'node:fs/promises';
await client.send({
to: 'user@example.com',
subject: 'Your invoice',
templateId: 'template-version-uuid',
type: 'transactional',
attachments: [
{ filename: 'invoice.pdf', content: await readFile('./invoice.pdf') },
{ filename: 'terms.pdf', url: 'https://files.yourdomain.com/terms.pdf' },
{ filename: 'logo.png', content: logoBytes, contentId: 'logo' }, // <img src="cid:logo">
],
});Limits and blocked file types are listed in the send endpoint reference.
Debug logging
Pass debug: true in the client options, or set DEBUG=ewyn in the environment. Requests, retries, and timeouts are then logged to stderr — useful for working out which step a failing send died on.