@ewyn/client
v0.9.0
Published
Official TypeScript SDK for Ewyn email service with full type safety
Readme
@ewyn/client
Official TypeScript SDK for the Ewyn email service with full type safety.
Installation
npm install @ewyn/client
# or
pnpm add @ewyn/client
# or
yarn add @ewyn/clientRequirements
- Node.js 18+ (uses native
fetch) - TypeScript 5.0+ (for type-safe features)
Quick Start
Basic Usage
import { Ewyn } from '@ewyn/client';
const client = new Ewyn({
apiKey: 'your-api-key',
});
// Send an email using template version ID
await client.send({
to: '[email protected]',
subject: 'Welcome!',
templateId: 'template-version-uuid',
variables: {
firstName: 'John',
lastName: 'Doe',
},
});Type-Safe Usage with Template Config
Get full TypeScript autocomplete and validation by copying your template config from the dashboard (or using fetch-config). The config exposes all non-deprecated versions per template so you can keep sending an older version even after publishing a new one.
import { Ewyn } from '@ewyn/client';
// 1. Copy template config from dashboard (API Keys page) or generate with fetch-config
const config = {
welcome: {
name: 'Welcome Email',
latest: 1,
versions: {
'1': {
id: 'version-uuid-1',
vars: {
firstName: { required: true },
lastName: { required: true },
plan: { required: false },
},
},
},
},
'password-reset': {
name: 'Password Reset',
latest: 1,
versions: {
'1': {
id: 'version-uuid-2',
vars: { resetUrl: { required: true } },
},
},
},
} as const; // ← Important: use 'as const'
// 2. Initialize with config
const client = new Ewyn({
apiKey: 'your-api-key',
templates: config,
});
// 3. Send with full type safety (defaults to latest version)
await client.send({
to: '[email protected]',
subject: 'Welcome!',
template: 'welcome',
variables: {
firstName: 'John',
lastName: 'Doe',
plan: 'Pro',
},
});
// 4. Or send a specific version (e.g. keep using v1 after v2 is published)
await client.send({
to: '[email protected]',
subject: 'Welcome!',
template: 'welcome',
version: 1,
variables: { firstName: 'John', lastName: 'Doe' },
});Getting Your Template Configuration
You can get your template config in three ways:
- CLI (recommended) – Run
npx @ewyn/client fetch-configto download config and generateewynTemplates.ts(see Fetching template config (CLI)). - Dashboard – Copy JSON from the API Keys page.
- API – Call the templates config endpoint with curl or your own code.
Fetching template config (CLI)
The easiest way to keep your template config in sync is to use the built-in CLI. From your project root (where you have an ewyn.config.ts or ewyn.config.js), run:
npx @ewyn/client fetch-configThis fetches your workspace’s template config from the API and writes a TypeScript file (e.g. ewynTemplates.ts) that you can import for type-safe sending.
Config file (ewyn.config.ts in project root):
apiKey(required): Your API key (e.g.process.env.EWYN_API_KEY)configurationPath(optional): Where to write the generated file (e.g../src/ewynTemplates.ts). If omitted, the file is written as./ewynTemplates.tsin the current directory.
Example ewyn.config.ts:
import type { EwynFetchConfig } from '@ewyn/client';
const config: EwynFetchConfig = {
apiKey: process.env.EWYN_API_KEY!,
configurationPath: './src/ewynTemplates.ts', // optional
};
export default config;After running fetch-config, import the generated config and pass it to the client:
import { Ewyn } from '@ewyn/client';
import { ewynTemplates } from './ewynTemplates'; // or from your configurationPath
const client = new Ewyn({
apiKey: process.env.EWYN_API_KEY!,
templates: ewynTemplates,
});Note: Regenerate the config after creating or updating templates (re-run npx @ewyn/client fetch-config). The config includes all non-deprecated versions per template, so regenerating does not force you to the latest version—you can still send with an older version by passing version.
From Dashboard
- Go to your dashboard → API Keys page
- Scroll to Template Configuration section
- Click Copy JSON or Download
- Paste into your code with
as const:
const config = {
// ... paste here
} as const;
const client = new Ewyn({
apiKey: 'your-api-key',
templates: config, // Now fully type-safe!
});Via API
Alternatively, fetch the config programmatically:
curl -X GET https://www.ewyn.ai/api/v1/templates/config \
-H "Authorization: Bearer YOUR_API_KEY"API Reference
Ewyn Class
Constructor
new Ewyn(options: EwynOptions)Options:
apiKey(string, required): Your API key secrettemplates(TemplateConfig, optional): Template configuration for name-based sendingmaxRetries(number, optional): Maximum retries for retryable errors (default: 3)timeout(number, optional): Request timeout in milliseconds (default: 30000)debug(boolean, optional): Log request/retry details to stderr. Also enabled when envDEBUGcontainsewyn.
Methods
send(options: SendEmailOptions): Promise<SendEmailResponse>
Send an email using a template.
Options:
to(string, required): Recipient email addresssubject(string, required): Email subject line. May contain{{variable}}placeholders.preheader(string, optional): Preview text. May contain{{variable}}placeholders.templateId(string, optional): Template version UUID (required iftemplatenot provided)template(string, optional): Template name (requirestemplatesconfig)version(number, optional): Major version number when usingtemplate(defaults to latest). Use this to keep sending an older version after publishing a new one.variables(Record<string, string>, optional): Variables to substitute in templatemetadata(Record<string, unknown>, optional): Additional metadata to attachidempotencyKey(string, optional): Key to prevent duplicate sends (valid for 24 hours)
Returns:
{
messageId: string;
status: 'queued';
queuedAt: string;
}Throws:
EwynApiError: If the API request failsError: If validation fails (missing template, missing variables, etc.)
Debug logging
To see which step is running (useful when something fails):
- CLI: The
fetch-configcommand logs progress to stdout (Using config: ...,Fetching template config from API...,Wrote ...). For extra detail (config paths, timing), setDEBUG=ewynbefore running. On errors, useDEBUG=ewynto print the full stack. - SDK: Pass
debug: truein the client options, or setDEBUG=ewynin the environment. Requests, retries, and timeouts are then logged to stderr.
Error Handling
The SDK throws EwynApiError for API errors:
import { Ewyn, EwynApiError } from '@ewyn/client';
try {
await client.send({ /* ... */ });
} catch (error) {
if (error instanceof EwynApiError) {
console.error('API Error:', error.status, error.message);
console.error('Details:', error.details);
if (error.isRetryable()) {
// Handle retryable error
}
}
}Error Properties:
status(number): HTTP status codecode(string, optional): Error codedetails(unknown, optional): Additional error detailsmessage(string): Error message
Error Methods:
isClientError(): Returnstruefor 4xx errorsisServerError(): Returnstruefor 5xx errorsisRetryable(): Returnstruefor 429 or 5xx errors
Idempotency
To prevent duplicate email sends, provide an idempotencyKey:
await client.send({
to: '[email protected]',
subject: 'Your subject',
templateId: 'template-uuid',
idempotencyKey: 'unique-request-id-123',
variables: { /* ... */ },
});If the same idempotencyKey is used within 24 hours, the API will return the original response instead of sending a duplicate email.
Retry Logic
The SDK automatically retries on:
- 429 (Too Many Requests)
- 5xx (Server Errors)
- Network errors
Retries use exponential backoff (1s, 2s, 4s) up to maxRetries (default: 3).
Examples
Check out the examples directory for comprehensive examples:
- Basic send - Simple sending with template ID
- Type-safe usage - Full type safety with template config
- ewyn.config example - Example config for
fetch-configCLI - Error handling - Comprehensive error handling patterns
- Idempotency - Preventing duplicate sends
- Advanced patterns - Batch sending, retries, and more
Testing
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watchDevelopment
# Build the SDK
pnpm build
# Watch mode for development
pnpm dev
# Lint
pnpm lintLicense
MIT
