Docs/SDK · @ewyn/client/Installation & usage

Installation & usage

@ewyn/client is the official TypeScript SDK — typed sends, automatic retries, idempotency, and contact management on top of the REST API.

v1 · beta

Install

bash
npm install @ewyn/client
# or
pnpm add @ewyn/client
# or
yarn add @ewyn/client

Requirements: Node.js 18+ (the SDK uses native fetch) and TypeScript 5.0+ for the type-safe features.

Create a client

typescript
import { Ewyn } from '@ewyn/client';

const client = new Ewyn({
  apiKey: process.env.EWYN_API_KEY!,
});

Constructor options:

OptionTypeDefaultNotes
apiKeystringrequiredYour workspace API key secret
templatesTemplateConfig—Template config for name-based, type-safe sending — see Type-safe templates
maxRetriesnumber3Maximum total attempts for retryable errors, including the first
timeoutnumber60000Request timeout in milliseconds
debugbooleanfalseLog requests/retries to stderr. Also enabled when env DEBUG contains ewyn

Send an email

typescript
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:

typescript
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.

typescript
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.

Was this page helpful?