JSPM

@euromail/sdk

0.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 16
  • Score
    100M100P100Q74428F
  • License MIT

Official TypeScript SDK for EuroMail transactional email service

Package Exports

  • @euromail/sdk

Readme

@euromail/sdk

Official TypeScript SDK for the EuroMail transactional email service.

Installation

npm install @euromail/sdk

Quick Start

import { EuroMail } from "@euromail/sdk";

const euromail = new EuroMail({
  apiKey: "em_live_your_api_key_here",
});

const result = await euromail.sendEmail({
  from: "sender@yourdomain.com",
  to: "recipient@example.com",
  subject: "Hello from EuroMail",
  html_body: "<h1>Welcome!</h1><p>Your account is ready.</p>",
});

console.log(`Email queued: ${result.id}`);

Configuration

const euromail = new EuroMail({
  apiKey: "em_live_...",     // Required
  timeout: 30000,            // Default: 30000ms
});

Sending Emails

Direct send

const result = await euromail.sendEmail({
  from: "noreply@yourdomain.com",
  to: "user@example.com",
  subject: "Order Confirmation",
  html_body: "<h1>Thanks for your order!</h1>",
  text_body: "Thanks for your order!",
  reply_to: "support@yourdomain.com",
  tags: ["order", "confirmation"],
  metadata: { order_id: "12345" },
});

Send with template

await euromail.sendEmail({
  from: "noreply@yourdomain.com",
  to: "user@example.com",
  template_alias: "welcome-email",
  template_data: {
    name: "John",
    activation_url: "https://example.com/activate/abc123",
  },
});

Send with attachments

await euromail.sendEmail({
  from: "noreply@yourdomain.com",
  to: "user@example.com",
  subject: "Your Invoice",
  html_body: "<p>Please find your invoice attached.</p>",
  attachments: [
    {
      filename: "invoice.pdf",
      content: base64EncodedContent,
      content_type: "application/pdf",
    },
  ],
});

Batch send

const batch = await euromail.sendBatch({
  emails: [
    {
      from: "noreply@yourdomain.com",
      to: "user1@example.com",
      subject: "Hello User 1",
      text_body: "Welcome aboard!",
    },
    {
      from: "noreply@yourdomain.com",
      to: "user2@example.com",
      subject: "Hello User 2",
      text_body: "Welcome aboard!",
    },
  ],
});

console.log(`Sent: ${batch.data.length}, Errors: ${batch.errors.length}`);

Idempotent sends

await euromail.sendEmail({
  from: "noreply@yourdomain.com",
  to: "user@example.com",
  subject: "Payment Receipt",
  html_body: "<p>Payment received.</p>",
  idempotency_key: "payment-receipt-12345",
});

Retrieve and list emails

const email = await euromail.getEmail("email-uuid");

const emails = await euromail.listEmails({
  page: 1,
  per_page: 50,
  status: "delivered",
});

Domains

// Add a sending domain
const domain = await euromail.addDomain("mail.yourdomain.com");
console.log("Configure these DNS records:", domain.dns_records);

// Trigger verification
const verification = await euromail.verifyDomain(domain.id);
if (verification.fully_verified) {
  console.log("Domain verified! SPF, DKIM, DMARC, and return-path all confirmed.");
}

// List all domains
const domains = await euromail.listDomains({ page: 1, per_page: 25 });

// Remove a domain
await euromail.deleteDomain(domain.id);

Templates

// Create a template with Jinja2-style variables
const template = await euromail.createTemplate({
  alias: "welcome-email",
  name: "Welcome Email",
  subject: "Welcome, {{ name }}!",
  html_body: "<h1>Hello {{ name }}</h1><p>Welcome to {{ company }}.</p>",
  text_body: "Hello {{ name }}, welcome to {{ company }}.",
});

// Update a template
await euromail.updateTemplate(template.id, {
  subject: "Welcome to {{ company }}, {{ name }}!",
});

// List and delete
const templates = await euromail.listTemplates({ page: 1, per_page: 25 });
await euromail.deleteTemplate(template.id);

Webhooks

// Subscribe to delivery events
const webhook = await euromail.createWebhook({
  url: "https://yourdomain.com/webhooks/euromail",
  events: ["delivered", "bounced", "complained", "email.inbound"],
});

// Update webhook
await euromail.updateWebhook(webhook.id, {
  url: "https://yourdomain.com/webhooks/v2",
  events: ["delivered", "bounced"],
  is_active: true,
});

// Send a test event
const test = await euromail.testWebhook(webhook.id);

// List and delete
const webhooks = await euromail.listWebhooks();
await euromail.deleteWebhook(webhook.id);

Supported events: sent, delivered, bounced, opened, clicked, complained, email.inbound

Suppressions

// Suppress an address manually
await euromail.addSuppression("bounced@example.com", "hard_bounce");

// List all suppressions
const suppressions = await euromail.listSuppressions({ page: 1, per_page: 50 });

// Remove a suppression
await euromail.deleteSuppression("bounced@example.com");

Contact Lists

// Create a list with double opt-in
const list = await euromail.createContactList({
  name: "Newsletter",
  description: "Monthly product updates",
  double_opt_in: true,
});

// Add a single contact
const contact = await euromail.addContact(list.id, {
  email: "user@example.com",
  metadata: { first_name: "Jane", source: "signup" },
});

// Bulk add contacts
const result = await euromail.bulkAddContacts(list.id, {
  contacts: [
    { email: "a@example.com", metadata: { name: "Alice" } },
    { email: "b@example.com", metadata: { name: "Bob" } },
  ],
});
console.log(`Inserted: ${result.inserted} of ${result.total_requested}`);

// List contacts with filters
const contacts = await euromail.listContacts(list.id, {
  page: 1,
  per_page: 50,
  status: "active",
});

// Remove a contact and delete the list
await euromail.removeContact(list.id, "user@example.com");
await euromail.deleteContactList(list.id);

Inbound Email

// List received emails
const inbound = await euromail.listInboundEmails({ page: 1, per_page: 25 });

// Get details
const email = await euromail.getInboundEmail("inbound-uuid");
console.log(`From: ${email.from_address}, Subject: ${email.subject}`);

// Delete
await euromail.deleteInboundEmail("inbound-uuid");

Inbound Routes

// Route incoming email to a webhook
const route = await euromail.createInboundRoute({
  domain_id: "domain-uuid",
  pattern: "support@",
  match_type: "prefix",
  priority: 10,
  webhook_url: "https://yourdomain.com/inbound/support",
});

// Update route
await euromail.updateInboundRoute(route.id, {
  webhook_url: "https://yourdomain.com/inbound/v2",
  is_active: true,
});

// Catch-all route
await euromail.createInboundRoute({
  domain_id: "domain-uuid",
  pattern: "*",
  match_type: "catch_all",
  priority: 100,
});

// List and delete
const routes = await euromail.listInboundRoutes();
await euromail.deleteInboundRoute(route.id);

Analytics

// Overview for the last 30 days
const overview = await euromail.getAnalyticsOverview({ period: "30d" });
console.log(`Delivery rate: ${overview.data.delivery_rate}%`);

// Custom date range
const custom = await euromail.getAnalyticsOverview({
  from: "2025-01-01",
  to: "2025-01-31",
});

// Time series data
const timeseries = await euromail.getAnalyticsTimeseries({
  period: "7d",
  metrics: "sent,delivered,bounced",
});

// Per-domain breakdown
const domains = await euromail.getAnalyticsDomains({
  period: "30d",
  limit: 10,
});

// Export as CSV
const csv = await euromail.exportAnalyticsCsv({ period: "30d" });

Account

const account = await euromail.getAccount();
console.log(`Plan: ${account.plan}, Used: ${account.emails_sent_this_month}/${account.monthly_quota}`);

// Export all account data (GDPR)
const exportData = await euromail.exportAccount();

// Delete account permanently
await euromail.deleteAccount();

Audit Logs

const logs = await euromail.listAuditLogs({ page: 1, per_page: 50 });
for (const log of logs.data) {
  console.log(`${log.created_at}: ${log.action} on ${log.resource_type}`);
}

Dead Letters

// List failed emails
const deadLetters = await euromail.listDeadLetters({ count: 20 });

// Retry delivery
await euromail.retryDeadLetter("dead-letter-uuid");

// Remove permanently
await euromail.deleteDeadLetter("dead-letter-uuid");

Error Handling

All API errors throw typed exceptions:

import {
  EuroMail,
  EuroMailError,
  AuthenticationError,
  RateLimitError,
  ValidationError,
} from "@euromail/sdk";

try {
  await euromail.sendEmail({ ... });
} catch (error) {
  if (error instanceof AuthenticationError) {
    // Invalid or missing API key (401)
    console.error("Check your API key");
  } else if (error instanceof ValidationError) {
    // Invalid request parameters (422)
    console.error(`${error.code}: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    // Too many requests (429)
    console.error(`Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof EuroMailError) {
    // Other API errors (4xx/5xx)
    console.error(`[${error.status}] ${error.code}: ${error.message}`);
  }
}

API Reference

Category Method Description
Emails sendEmail(params) Send a single email
sendBatch(params) Send up to 500 emails in one request
getEmail(id) Get email details and status
listEmails(params?) List emails with pagination and status filter
Templates createTemplate(params) Create an email template
getTemplate(id) Get template by ID
updateTemplate(id, params) Update template fields
deleteTemplate(id) Delete a template
listTemplates(params?) List templates with pagination
Domains addDomain(domain) Register a sending domain
getDomain(id) Get domain details and DNS records
verifyDomain(id) Trigger DNS verification
deleteDomain(id) Remove a domain
listDomains(params?) List domains with pagination
Webhooks createWebhook(params) Subscribe to events
getWebhook(id) Get webhook details
updateWebhook(id, params) Update URL, events, or status
testWebhook(id) Send a test event
deleteWebhook(id) Remove a webhook
listWebhooks(params?) List webhooks with pagination
Suppressions addSuppression(email, reason?) Suppress an email address
deleteSuppression(email) Remove a suppression
listSuppressions(params?) List suppressions with pagination
Contact Lists createContactList(params) Create a contact list
getContactList(id) Get list details
updateContactList(id, params) Update list settings
deleteContactList(id) Delete a list
listContactLists() List all contact lists
addContact(listId, params) Add a contact to a list
bulkAddContacts(listId, params) Add multiple contacts
listContacts(listId, params?) List contacts with filters
removeContact(listId, email) Remove a contact
Inbound listInboundEmails(params?) List received emails
getInboundEmail(id) Get inbound email details
deleteInboundEmail(id) Delete an inbound email
Inbound Routes createInboundRoute(params) Create a routing rule
getInboundRoute(id) Get route details
updateInboundRoute(id, params) Update a route
deleteInboundRoute(id) Delete a route
listInboundRoutes(params?) List routes with pagination
Analytics getAnalyticsOverview(query?) Aggregated delivery stats
getAnalyticsTimeseries(query?) Daily metrics over time
getAnalyticsDomains(query?) Per-domain breakdown
exportAnalyticsCsv(query?) Export stats as CSV
Audit Logs listAuditLogs(params?) List account activity
Dead Letters listDeadLetters(params?) List permanently failed emails
retryDeadLetter(id) Retry delivery
deleteDeadLetter(id) Remove from dead letter queue
Account getAccount() Get account info and quota
exportAccount() Export all account data
deleteAccount() Permanently delete account

Agent Mailboxes

Agent mailboxes provide persistent email addresses for AI agents with at-least-once message delivery via a lease/ack/nack model. The SDK wraps the full lifecycle natively:

import { EuroMail } from "@euromail/sdk";

const euromail = new EuroMail({ apiKey: process.env.EUROMAIL_API_KEY });

// Create a mailbox
const mailbox = await euromail.createMailbox({ display_name: "Support Agent" });

// Long-poll loop for incoming messages
while (true) {
  const leased = await euromail.waitForNextMessage(mailbox.id, { timeout: 30 });
  if (!leased) continue; // 408 timeout — no message arrived, poll again

  const { data: msg, lease_token } = leased;
  try {
    await handle(msg);
    // Ack when done — message will not be redelivered
    await euromail.ackMessage(mailbox.id, msg.id, lease_token);
  } catch (err) {
    // Nack to return the message to the queue for retry
    await euromail.nackMessage(mailbox.id, msg.id, lease_token);
    throw err;
  }
}

Other mailbox methods:

  • listMailboxes({ limit, offset }) — list mailboxes on the account
  • getMailbox(id) — fetch a single mailbox
  • deleteMailbox(id) — remove a mailbox
  • listMessages(mailboxId, { status, limit, offset }) — list messages without acquiring a lease
  • deleteMessage(mailboxId, messageId) — permanently delete a message

See the Agent Mailboxes guide for the full flow, duplicate handling, and horizontal scaling patterns.

Requirements

  • Node.js 18+ (uses native fetch)
  • TypeScript 5.0+ (for type definitions)

License

MIT