Skip to content

JavaScript/TypeScript Client

The MailOven JavaScript client provides a type-safe, convenient way to interact with the MailOven API from Node.js, Bun, Deno, or the browser.

Installation

sh
npm install -D @mailoven/client
sh
yarn add -D @mailoven/client
sh
pnpm add -D @mailoven/client
sh
bun add -D @mailoven/client
sh
deno add -D npm:@mailoven/client

Basic Setup

typescript
import { MailOvenClient } from "@mailoven/client";

const mailoven = new MailOvenClient({
  apiKey: process.env.MAILOVEN_API_KEY,
  slug: "acme", // your organization slug
});

Configuration

typescript
const mailoven = new MailOvenClient({
  apiKey: "mo_your_api_key",
  slug: "acme", // your organization slug
  timeout: 10_000, // optional, polling timeout in ms (default: 10000)
  interval: 500, // optional, polling interval in ms (default: 500)
});

Methods

Get a single email

typescript
const email = await mailoven.getEmail("email-id");
console.log(email.subject, email.bodyText, email.fromAddress);

List and search emails

typescript
// List all emails in an inbox
const emails = await mailoven.listEmails({ to: "signup" });

// Search by subject
const emails = await mailoven.listEmails({
  to: "signup",
  filter: { subject: "verification" },
});

// Search by body
const emails = await mailoven.listEmails({
  to: "notifications",
  filter: { body: "order confirmation" },
});

// Full-text search (subject + body)
const emails = await mailoven.listEmails({
  to: "support",
  filter: { search: "urgent" },
});

// Limit results
const emails = await mailoven.listEmails({ to: "inbox", limit: 5 });

// Emails since a timestamp
const emails = await mailoven.listEmails({
  to: "test",
  since: Math.floor(Date.now() / 1000) - 60, // last 60 seconds
});

Wait for an email (polling)

The client includes built-in polling utilities for testing:

typescript
// Wait for one email
const email = await mailoven.waitForEmail({ to: "signup" });

// Wait with a subject filter
const email = await mailoven.waitForEmail({
  to: "signup",
  filter: { subject: "Verify your email" },
});

// Wait for multiple emails
const emails = await mailoven.waitForEmails(
  { to: "notifications" },
  { count: 3 }, // wait until 3 emails arrive
);

// Custom timeout
const email = await mailoven.waitForEmail(
  { to: "test" },
  { timeout: 30_000 }, // wait up to 30 seconds
);

// Custom polling interval
const email = await mailoven.waitForEmail(
  { to: "test" },
  { interval: 1_000 }, // check every 1 second instead of 500ms
);

Delete emails

typescript
// Delete a single email
await mailoven.deleteEmail("email-id");

// Delete all emails in an inbox
await mailoven.deleteInbox("signup");

Helpers

The client exposes two convenience helpers that use your org slug:

typescript
// Get the full email address for an inbox
mailoven.getEmailAddress("signup");
// → "signup@acme.mailoven.com"

// Get the MailOven inbox URL (useful for linking to the inbox in test output)
mailoven.getInboxEndpoint("signup");
// → "https://mailoven.com/inbox/signup%40acme.mailoven.com"

Error Handling

The client throws specific error types for different scenarios:

typescript
import {
  MailOvenError,
  MailOvenAuthError,
  MailOvenInputError,
  MailOvenNetworkError,
  MailOvenNotFoundError,
  MailOvenValidationError,
  MailOvenRateLimitError,
  MailOvenTimeoutError,
} from "@mailoven/client";

try {
  const email = await mailoven.waitForEmail({ to: "test" });
} catch (error) {
  if (error instanceof MailOvenTimeoutError) {
    console.log("No email arrived within timeout");
  } else if (error instanceof MailOvenInputError) {
    console.log("Invalid argument", error.message);
  } else if (error instanceof MailOvenAuthError) {
    console.log("Invalid API key");
  } else if (error instanceof MailOvenRateLimitError) {
    console.log(`Rate limited, retry after ${error.retryAfter}`);
  } else if (error instanceof MailOvenNetworkError) {
    console.log("Connection failed", error.cause);
  } else if (error instanceof MailOvenValidationError) {
    console.log("Invalid request parameters");
  } else if (error instanceof MailOvenNotFoundError) {
    console.log("Email not found");
  }
}

MailOvenInputError is thrown synchronously (before any network call) when you pass invalid arguments to client methods — for example a limit of 0, a negative timeout, or a count less than 1. These represent programming mistakes rather than runtime failures, so no retry logic is needed.

TypeScript Types

typescript
import type {
  Email,
  EmailFilter,
  ListEmailsParams,
  MailOvenClientOptions,
  PollOptions,
} from "@mailoven/client";

interface Email {
  id: string;
  toAddress: string;
  fromAddress: string;
  fromName: string;
  subject: string | null;
  bodyText: string | null;
  bodyHtml: string | null;
  receivedAt: Date;
  read: boolean;
  dkim: string | null;
  dkimComment: string | null;
  spf: string | null;
  spfComment: string | null;
  dmarc: string | null;
  dmarcComment: string | null;
  tls: boolean | null;
}

type EmailFilter =
  | { subject: string } // case-insensitive substring match on subject
  | { body: string } // case-insensitive substring match on plain-text body
  | { search: string }; // case-insensitive match on subject OR body

interface ListEmailsParams {
  to: string; // local part (e.g. "signup" for signup@acme.mailoven.com)
  filter?: EmailFilter;
  limit?: number; // 1–10, defaults to 10
  since?: Date | number; // Date object or Unix timestamp in seconds
}

interface MailOvenClientOptions {
  apiKey: string;
  slug: string; // your organization slug
  timeout?: number; // polling timeout in ms, default 10000
  interval?: number; // polling interval in ms, default 500
}

interface PollOptions {
  timeout?: number;
  interval?: number;
}

Disposable email inboxes for every teams