Skip to content

Inbox API

The Inbox class represents a single email inbox in VaultSandbox. It provides methods for managing emails, waiting for new messages, and monitoring in real-time.

emailAddress: string;

The email address for this inbox. Use this address to send test emails.

const inbox = await client.createInbox();
console.log(`Send email to: ${inbox.emailAddress}`);
// Use in your application
await sendWelcomeEmail(inbox.emailAddress);

inboxHash: string;

Unique identifier for this inbox. Used internally for API operations.

console.log(`Inbox ID: ${inbox.inboxHash}`);

expiresAt: Date;

The date and time when this inbox will expire and be automatically deleted.

const inbox = await client.createInbox();
console.log(`Inbox expires at: ${inbox.expiresAt.toISOString()}`);
const timeUntilExpiry = inbox.expiresAt.getTime() - Date.now();
console.log(`Time remaining: ${Math.round(timeUntilExpiry / 1000)}s`);

emailAuth: boolean;

Whether email authentication checks (SPF/DKIM/DMARC/PTR) are enabled for this inbox.

const inbox = await client.createInbox({ emailAuth: false });
console.log(`Email auth enabled: ${inbox.emailAuth}`); // false
// When emailAuth is false, auth results will show "skipped" status
const email = await inbox.waitForEmail({ timeout: 10000 });
console.log(email.authResults.spf?.result); // "skipped"

encrypted: boolean;

Whether this inbox uses end-to-end encryption. When true, emails are encrypted at rest and the serverSigPk property is available.

const inbox = await client.createInbox();
console.log(`Inbox encrypted: ${inbox.encrypted}`);
if (inbox.encrypted) {
// Inbox uses end-to-end encryption
// Emails are automatically decrypted by the SDK
}

spamAnalysis?: boolean;

Whether spam analysis is enabled for this inbox. This property reflects the spam analysis setting that was requested at inbox creation time.

  • true - Spam analysis is enabled for emails to this inbox
  • false - Spam analysis is disabled for this inbox
  • undefined - Using server default setting
// Create inbox with spam analysis enabled
const inbox = await client.createInbox({ spamAnalysis: true });
console.log(`Spam analysis enabled: ${inbox.spamAnalysis}`); // true
// Check if spam analysis is active
if (inbox.spamAnalysis) {
const email = await inbox.waitForEmail({ timeout: 10000 });
if (email.spamAnalysis?.status === 'analyzed') {
console.log(`Spam score: ${email.getSpamScore()}`);
}
}

Lists all emails in the inbox with full content. Emails are automatically decrypted. This method fetches all email content in a single efficient API call.

listEmails(): Promise<Email[]>

Promise<Email[]> - Array of decrypted email objects with full content (text, html, attachments, etc.)

const emails = await inbox.listEmails();
console.log(`Inbox has ${emails.length} emails`);
emails.forEach((email) => {
console.log(`- ${email.subject} from ${email.from}`);
console.log(` Body: ${email.text?.substring(0, 100)}...`);
});

Lists all emails in the inbox with metadata only (no content). Use this for efficient listing when you only need basic email information.

listEmailsMetadataOnly(): Promise<EmailMetadata[]>

Promise<EmailMetadata[]> - Array of email metadata objects

interface EmailMetadata {
id: string;
from: string;
subject: string;
receivedAt: Date;
isRead: boolean;
}
// Quickly list emails without fetching full content
const emails = await inbox.listEmailsMetadataOnly();
console.log(`Inbox has ${emails.length} emails`);
emails.forEach((email) => {
console.log(`- ${email.subject} from ${email.from}`);
console.log(` Received: ${email.receivedAt.toISOString()}`);
console.log(` Read: ${email.isRead}`);
});
// Fetch full content for a specific email if needed
const fullEmail = await inbox.getEmail(emails[0].id);
console.log(`Body: ${fullEmail.text}`);
  • Displaying email lists in a UI
  • Checking for new emails before fetching content
  • Reducing bandwidth when full content isn’t needed

Retrieves a specific email by ID.

getEmail(emailId: string): Promise<Email>
  • emailId: The unique identifier for the email

Promise<Email> - The decrypted email object

const emails = await inbox.listEmails();
const firstEmail = await inbox.getEmail(emails[0].id);
console.log(`Subject: ${firstEmail.subject}`);
console.log(`Body: ${firstEmail.text}`);
  • EmailNotFoundError - Email does not exist

Waits for an email matching specified criteria. This is the recommended way to handle email arrival in tests.

waitForEmail(options: WaitOptions): Promise<Email>
interface WaitOptions {
timeout?: number;
pollInterval?: number;
subject?: string | RegExp;
from?: string | RegExp;
predicate?: (email: Email) => boolean;
}
PropertyTypeDefaultDescription
timeoutnumber30000Maximum time to wait in milliseconds
pollIntervalnumber2000Polling interval in milliseconds
subjectstring | RegExp-Filter by email subject
fromstring | RegExp-Filter by sender address
predicate(email: Email) => boolean-Custom filter function

Promise<Email> - The first email matching the criteria

// Wait for any email
const email = await inbox.waitForEmail({ timeout: 10000 });
// Wait for email with specific subject
const email = await inbox.waitForEmail({
timeout: 10000,
subject: /Password Reset/,
});
// Wait for email from specific sender
const email = await inbox.waitForEmail({
timeout: 10000,
from: 'noreply@example.com',
});
// Wait with custom predicate
const email = await inbox.waitForEmail({
timeout: 15000,
predicate: (email) => email.to.includes('user@example.com'),
});
// Combine multiple filters
const email = await inbox.waitForEmail({
timeout: 10000,
subject: /Welcome/,
from: /noreply@/,
predicate: (email) => email.links.length > 0,
});
  • TimeoutError - No matching email received within timeout period

Waits until the inbox has at least the specified number of emails. More efficient than using arbitrary timeouts when testing multiple emails.

waitForEmailCount(count: number, options?: WaitForCountOptions): Promise<void>
  • count: Minimum number of emails to wait for
interface WaitForCountOptions {
timeout?: number;
}
PropertyTypeDefaultDescription
timeoutnumber30000Maximum time to wait in milliseconds

Promise<void> - Resolves when count is reached

// Trigger multiple emails
await sendMultipleNotifications(inbox.emailAddress, 3);
// Wait for all 3 to arrive
await inbox.waitForEmailCount(3, { timeout: 30000 });
// Now process all emails
const emails = await inbox.listEmails();
expect(emails.length).toBe(3);
  • TimeoutError - Required count not reached within timeout

Subscribes to new emails in real-time. Receives a callback for each new email that arrives.

onNewEmail(callback: (email: Email) => void): Subscription
  • callback: Function called when a new email arrives

Subscription - Subscription object with unsubscribe() method

interface Subscription {
unsubscribe(): void;
}
const inbox = await client.createInbox();
console.log(`Monitoring: ${inbox.emailAddress}`);
// Subscribe to new emails
const subscription = inbox.onNewEmail((email) => {
console.log(`New email: "${email.subject}"`);
console.log(`From: ${email.from}`);
// Process email...
});
// Later, stop monitoring
subscription.unsubscribe();

Always unsubscribe when done to avoid memory leaks:

let subscription;
beforeEach(async () => {
inbox = await client.createInbox();
subscription = inbox.onNewEmail((email) => {
// Handle email
});
});
afterEach(async () => {
if (subscription) {
subscription.unsubscribe();
}
if (inbox) {
await inbox.delete();
}
});

Gets the current synchronization status of the inbox with the server.

getSyncStatus(): Promise<SyncStatus>

Promise<SyncStatus> - Sync status information

interface SyncStatus {
emailCount: number;
emailsHash: string;
}
const status = await inbox.getSyncStatus();
console.log(`Email count: ${status.emailCount}`);
console.log(`Emails hash: ${status.emailsHash}`);

Gets the raw, decrypted source of a specific email (original MIME format).

getRawEmail(emailId: string): Promise<RawEmail>
  • emailId: The unique identifier for the email

Promise<RawEmail> - Raw email source

interface RawEmail {
id: string;
raw: string;
}
const emails = await inbox.listEmails();
const raw = await inbox.getRawEmail(emails[0].id);
console.log('Raw MIME source:');
console.log(raw.raw);
// Save to file for debugging
fs.writeFileSync('email.eml', raw.raw);

Marks a specific email as read.

markEmailAsRead(emailId: string): Promise<void>
  • emailId: The unique identifier for the email
const emails = await inbox.listEmails();
await inbox.markEmailAsRead(emails[0].id);
console.log('Email marked as read');

Deletes a specific email from the inbox.

deleteEmail(emailId: string): Promise<void>
  • emailId: The unique identifier for the email
const emails = await inbox.listEmails();
// Delete first email
await inbox.deleteEmail(emails[0].id);
console.log('Email deleted');
// Verify deletion
const updated = await inbox.listEmails();
expect(updated.length).toBe(emails.length - 1);

Deletes this inbox and all its emails.

delete(): Promise<void>
const inbox = await client.createInbox();
// Use inbox...
// Clean up
await inbox.delete();
console.log('Inbox deleted');

Always delete inboxes after tests:

afterEach(async () => {
if (inbox) {
await inbox.delete();
}
});

Exports inbox data and encryption keys for backup or sharing.

export(): ExportedInboxData

ExportedInboxData - Serializable inbox data including sensitive keys

interface ExportedInboxData {
version: number; // Export format version (currently 1)
emailAddress: string;
inboxHash: string;
expiresAt: string; // ISO 8601 timestamp
serverSigPk: string; // ML-DSA-65 public key (base64url)
secretKey: string; // ML-KEM-768 secret key (base64url)
exportedAt: string; // ISO 8601 timestamp
}
const inbox = await client.createInbox();
const data = inbox.export();
// Save for later
fs.writeFileSync('inbox-backup.json', JSON.stringify(data, null, 2));

Exported data contains private encryption keys. Store securely!

The Inbox class provides methods for managing webhooks that receive HTTP callbacks when events occur.

Creates a new webhook for this inbox.

createWebhook(options: CreateWebhookOptions): Promise<WebhookData>
interface CreateWebhookOptions {
url: string;
events: WebhookEventType[];
template?: 'slack' | 'discord' | 'teams' | 'simple' | 'notification' | 'zapier' | 'default' | CustomTemplate;
filter?: FilterConfig;
description?: string;
}
type WebhookEventType = 'email.received' | 'email.stored' | 'email.deleted';

Promise<WebhookData> - The created webhook including the secret for signature verification

const webhook = await inbox.createWebhook({
url: 'https://your-app.com/webhook/emails',
events: ['email.received'],
description: 'Production email notifications',
});
console.log(`Webhook ID: ${webhook.id}`);
console.log(`Secret: ${webhook.secret}`); // Save this!

Lists all webhooks for this inbox.

listWebhooks(): Promise<WebhookListResponse>

Promise<WebhookListResponse> - List of webhooks and total count

interface WebhookListResponse {
webhooks: WebhookData[];
total: number;
}
const { webhooks, total } = await inbox.listWebhooks();
console.log(`Total webhooks: ${total}`);
webhooks.forEach((wh) => {
console.log(`- ${wh.id}: ${wh.url}`);
});

Retrieves a specific webhook by ID.

getWebhook(webhookId: string): Promise<WebhookData>
  • webhookId: The unique identifier for the webhook

Promise<WebhookData> - The webhook data

interface WebhookData {
id: string;
url: string;
events: WebhookEventType[];
scope: 'global' | 'inbox';
inboxEmail?: string;
enabled: boolean;
secret?: string;
template?: unknown;
filter?: FilterConfig;
description?: string;
createdAt: string;
updatedAt?: string;
lastDeliveryAt?: string;
lastDeliveryStatus?: 'success' | 'failed';
stats?: WebhookStats;
}
const webhook = await inbox.getWebhook('webhook-id');
console.log(`URL: ${webhook.url}`);
console.log(`Enabled: ${webhook.enabled}`);
console.log(`Last delivery: ${webhook.lastDeliveryAt || 'Never'}`);
  • WebhookNotFoundError - Webhook does not exist

Updates a specific webhook.

updateWebhook(webhookId: string, options: UpdateWebhookOptions): Promise<WebhookData>
  • webhookId: The unique identifier for the webhook
interface UpdateWebhookOptions {
url?: string;
events?: WebhookEventType[];
template?: string | CustomTemplate | null;
filter?: FilterConfig | null;
description?: string;
enabled?: boolean;
}

Promise<WebhookData> - The updated webhook data

const updated = await inbox.updateWebhook('webhook-id', {
url: 'https://your-app.com/webhook/v2/emails',
enabled: false,
});
console.log(`Updated URL: ${updated.url}`);
  • WebhookNotFoundError - Webhook does not exist

Deletes a specific webhook.

deleteWebhook(webhookId: string): Promise<void>
  • webhookId: The unique identifier for the webhook
await inbox.deleteWebhook('webhook-id');
console.log('Webhook deleted');
  • WebhookNotFoundError - Webhook does not exist

Tests a webhook by sending a test payload.

testWebhook(webhookId: string): Promise<TestWebhookResponse>
  • webhookId: The unique identifier for the webhook

Promise<TestWebhookResponse> - The test result

interface TestWebhookResponse {
success: boolean;
statusCode?: number;
responseTime?: number;
responseBody?: string;
error?: string;
payloadSent?: unknown;
}
const result = await inbox.testWebhook('webhook-id');
if (result.success) {
console.log(`Test passed! Status: ${result.statusCode}`);
console.log(`Response time: ${result.responseTime}ms`);
} else {
console.error(`Test failed: ${result.error}`);
}
  • WebhookNotFoundError - Webhook does not exist

Rotates the secret for a webhook. The old secret remains valid for a grace period.

rotateWebhookSecret(webhookId: string): Promise<RotateSecretResponse>
  • webhookId: The unique identifier for the webhook

Promise<RotateSecretResponse> - The new secret and grace period

interface RotateSecretResponse {
id: string;
secret: string;
previousSecretValidUntil: string;
}
const result = await inbox.rotateWebhookSecret('webhook-id');
console.log(`New secret: ${result.secret}`);
console.log(`Old secret valid until: ${result.previousSecretValidUntil}`);
  • WebhookNotFoundError - Webhook does not exist

The Inbox class provides methods for configuring chaos engineering features to test email resilience. Chaos must be enabled on the gateway server.

Gets the current chaos configuration for this inbox.

getChaosConfig(): Promise<ChaosConfigResponse>

Promise<ChaosConfigResponse> - The current chaos configuration

interface ChaosConfigResponse {
enabled: boolean;
expiresAt?: string;
latency?: LatencyConfig;
connectionDrop?: ConnectionDropConfig;
randomError?: RandomErrorConfig;
greylist?: GreylistConfig;
blackhole?: BlackholeConfig;
}
const config = await inbox.getChaosConfig();
console.log(`Chaos enabled: ${config.enabled}`);
if (config.latency?.enabled) {
console.log(`Latency: ${config.latency.minDelayMs}-${config.latency.maxDelayMs}ms`);
}
  • ApiError (403) - Chaos features are disabled on the server

Sets or updates the chaos configuration for this inbox.

setChaosConfig(config: ChaosConfigRequest): Promise<ChaosConfigResponse>
interface ChaosConfigRequest {
enabled: boolean;
expiresAt?: string;
latency?: LatencyConfig;
connectionDrop?: ConnectionDropConfig;
randomError?: RandomErrorConfig;
greylist?: GreylistConfig;
blackhole?: BlackholeConfig;
}
PropertyTypeRequiredDescription
enabledbooleanYesMaster switch for chaos features
expiresAtstringNoISO 8601 timestamp for auto-disable
latencyLatencyConfigNoLatency injection configuration
connectionDropConnectionDropConfigNoConnection drop configuration
randomErrorRandomErrorConfigNoRandom error configuration
greylistGreylistConfigNoGreylisting simulation configuration
blackholeBlackholeConfigNoBlackhole mode configuration

Promise<ChaosConfigResponse> - The updated chaos configuration

const config = await inbox.setChaosConfig({
enabled: true,
latency: {
enabled: true,
minDelayMs: 1000,
maxDelayMs: 5000,
jitter: true,
probability: 0.5,
},
randomError: {
enabled: true,
errorRate: 0.1,
errorTypes: ['temporary'],
},
});
console.log('Chaos configured:', config);
  • ApiError (403) - Chaos features are disabled on the server
  • InboxNotFoundError - Inbox does not exist

Disables all chaos features for this inbox.

disableChaos(): Promise<void>
// Disable all chaos features
await inbox.disableChaos();
console.log('Chaos disabled');
  • ApiError (403) - Chaos features are disabled on the server
  • InboxNotFoundError - Inbox does not exist

The InboxMonitor class allows you to monitor multiple inboxes simultaneously.

const inbox1 = await client.createInbox();
const inbox2 = await client.createInbox();
const monitor = client.monitorInboxes([inbox1, inbox2]);

Emitted when a new email arrives in any monitored inbox.

on(event: 'email', listener: (inbox: Inbox, email: Email) => void): this
  • inbox: The inbox that received the email
  • email: The email that was received
monitor.on('email', (inbox, email) => {
console.log(`Email received in ${inbox.emailAddress}`);
console.log(`Subject: ${email.subject}`);
});

Stops monitoring all inboxes and cleans up resources.

unsubscribe(): void
const monitor = client.monitorInboxes([inbox1, inbox2]);
// Use monitor...
// Stop monitoring
monitor.unsubscribe();
import { VaultSandboxClient } from '@vaultsandbox/client';
async function monitorMultipleInboxes() {
const client = new VaultSandboxClient({ url, apiKey });
// Create multiple inboxes
const inbox1 = await client.createInbox();
const inbox2 = await client.createInbox();
console.log(`Inbox 1: ${inbox1.emailAddress}`);
console.log(`Inbox 2: ${inbox2.emailAddress}`);
// Monitor both inboxes
const monitor = client.monitorInboxes([inbox1, inbox2]);
monitor.on('email', (inbox, email) => {
console.log(`\nNew email in ${inbox.emailAddress}:`);
console.log(` Subject: ${email.subject}`);
console.log(` From: ${email.from}`);
});
// Wait for emails to arrive...
await new Promise((resolve) => setTimeout(resolve, 60000));
// Clean up
monitor.unsubscribe();
await inbox1.delete();
await inbox2.delete();
}
monitorMultipleInboxes().catch(console.error);
import { VaultSandboxClient } from '@vaultsandbox/client';
async function completeInboxExample() {
const client = new VaultSandboxClient({
url: process.env.VAULTSANDBOX_URL,
apiKey: process.env.VAULTSANDBOX_API_KEY,
});
try {
// Create inbox
const inbox = await client.createInbox();
console.log(`Created: ${inbox.emailAddress}`);
console.log(`Expires: ${inbox.expiresAt.toISOString()}`);
// Subscribe to new emails
const subscription = inbox.onNewEmail((email) => {
console.log(`Received: ${email.subject}`);
});
// Trigger test email
await sendTestEmail(inbox.emailAddress);
// Wait for specific email
const email = await inbox.waitForEmail({
timeout: 10000,
subject: /Test/,
});
console.log(`Found email: ${email.subject}`);
console.log(`Body: ${email.text}`);
// Mark as read
await inbox.markEmailAsRead(email.id);
// Get all emails
const allEmails = await inbox.listEmails();
console.log(`Total emails: ${allEmails.length}`);
// Export inbox
const exportData = inbox.export();
fs.writeFileSync('inbox.json', JSON.stringify(exportData));
// Clean up
subscription.unsubscribe();
await inbox.delete();
} finally {
await client.close();
}
}
completeInboxExample().catch(console.error);