Inboxes
Inboxes are the core concept in VaultSandbox. Each inbox is an isolated, encrypted email destination with its own unique address and encryption keys.
What is an Inbox?
Section titled “What is an Inbox?”An inbox is a temporary, encrypted email destination that:
- Has a unique email address (e.g.,
[email protected]) - Uses client-side encryption (ML-KEM-768 keypair)
- Expires automatically after a configurable time-to-live (TTL)
- Is isolated from other inboxes
- Stores emails in memory on the gateway
Creating Inboxes
Section titled “Creating Inboxes”Basic Creation
Section titled “Basic Creation”import { VaultSandboxClient } from '@vaultsandbox/client';
const client = new VaultSandboxClient({ url, apiKey });const inbox = await client.createInbox();
console.log(inbox.inboxHash); // "a1b2c3d4"console.log(inbox.expiresAt); // Date objectWith Options
Section titled “With Options”const inbox = await client.createInbox({ ttl: 3600, // 1 hour (default: 24 hours)});Note: Requesting a specific email address may fail if it’s already in use. The server will return an error.
Inbox Properties
Section titled “Inbox Properties”emailAddress
Section titled “emailAddress”Type: string
The full email address for this inbox.
console.log(inbox.emailAddress);// "[email protected]"Send emails to this address to have them appear in the inbox.
inboxHash
Section titled “inboxHash”Type: string
A unique cryptographic hash identifier for the inbox. This is used internally for encryption and identification purposes.
console.log(inbox.inboxHash);// "Rr02MLnP7F0pRVC6QdcpSIeyklqu3PDkYglvsfN7Oss"Note: This is not the same as the local part of the email address. The email address local part (e.g., a1b2c3d4 in [email protected]) is different from the inboxHash.
expiresAt
Section titled “expiresAt”Type: Date
When the inbox will automatically expire and be deleted.
console.log(inbox.expiresAt);// Check if inbox is expiring soonconst hoursUntilExpiry = (inbox.expiresAt - new Date()) / 1000 / 60 / 60;console.log(`Expires in ${hoursUntilExpiry} hours`);Inbox Lifecycle
Section titled “Inbox Lifecycle”┌─────────────────────────────────────────────────────────┐│ Inbox Lifecycle │└─────────────────────────────────────────────────────────┘
1. Creation client.createInbox() → Inbox object ↓ - Keypair generated client-side - Public key sent to server - Unique email address assigned - TTL timer starts
2. Active ↓ - Receive emails - List/read emails - Wait for emails - Monitor for new emails
3. Expiration (TTL reached) or Manual Deletion ↓ inbox.delete() or TTL expires - All emails deleted - Inbox address freed - Keypair destroyedWorking with Inboxes
Section titled “Working with Inboxes”Listing Emails
Section titled “Listing Emails”const emails = await inbox.listEmails();
console.log(`${emails.length} emails in inbox`);emails.forEach((email) => { console.log(`${email.from}: ${email.subject}`);});Getting a Specific Email
Section titled “Getting a Specific Email”const email = await inbox.getEmail('email-id-123');
console.log(email.subject);console.log(email.text);Waiting for Emails
Section titled “Waiting for Emails”// Wait for any emailconst email = await inbox.waitForEmail({ timeout: 30000 });
// Wait for specific emailconst email = await inbox.waitForEmail({ timeout: 30000, subject: /Password Reset/,});Deleting Emails
Section titled “Deleting Emails”// Delete specific emailawait inbox.deleteEmail('email-id-123');
// Or via email objectawait email.delete();Deleting Inbox
Section titled “Deleting Inbox”// Delete inbox and all its emailsawait inbox.delete();Inbox Isolation
Section titled “Inbox Isolation”Each inbox is completely isolated:
const inbox1 = await client.createInbox();const inbox2 = await client.createInbox();
// inbox1 cannot access inbox2's emails// inbox2 cannot access inbox1's emails
// Each has its own:// - Email address// - Encryption keys// - Email storage// - Expiration timeTime-to-Live (TTL)
Section titled “Time-to-Live (TTL)”Inboxes automatically expire after their TTL:
Default TTL
Section titled “Default TTL”// Uses server's DEFAULT_INBOX_TTL (typically 24 hours)const inbox = await client.createInbox();Custom TTL
Section titled “Custom TTL”// Expire after 1 hourconst inbox = await client.createInbox({ ttl: 3600 });
// Expire after 10 minutes (useful for quick tests)const inbox = await client.createInbox({ ttl: 600 });
// Expire after 7 daysconst inbox = await client.createInbox({ ttl: 604800 });Checking Expiration
Section titled “Checking Expiration”const minutesLeft = (inbox.expiresAt - new Date()) / 1000 / 60;
if (minutesLeft < 5) { console.warn('Inbox expiring soon!');}Import and Export
Section titled “Import and Export”Inboxes can be exported and imported for:
- Test reproducibility
- Sharing between environments
- Backup and restore
Export
Section titled “Export”const exportData = inbox.export();
// Save to filefs.writeFileSync('inbox.json', JSON.stringify(exportData));Import
Section titled “Import”const exportData = JSON.parse(fs.readFileSync('inbox.json', 'utf8'));const inbox = await client.importInbox(exportData);
// Inbox restored with all encryption keysSecurity Warning: Exported data contains private keys. Treat as sensitive.
Best Practices
Section titled “Best Practices”CI/CD Pipelines
Section titled “CI/CD Pipelines”Short TTL for fast cleanup:
const inbox = await client.createInbox({ ttl: 3600 }); // 1 hourAlways clean up:
try { const inbox = await client.createInbox(); // Run tests} finally { await inbox.delete();}Manual Testing
Section titled “Manual Testing”Longer TTL for convenience:
const inbox = await client.createInbox({ ttl: 86400 }); // 24 hoursExport for reuse:
// Export after creatingconst exportData = inbox.export();fs.writeFileSync('test-inbox.json', JSON.stringify(exportData));
// Reuse in later sessionsconst inbox = await client.importInbox(exportData);Production Monitoring
Section titled “Production Monitoring”Monitor expiration:
setInterval(() => { const minutesLeft = (inbox.expiresAt - new Date()) / 1000 / 60; if (minutesLeft < 10) { console.warn(`Inbox ${inbox.emailAddress} expiring in ${minutesLeft} minutes`); }}, 60000); // Check every minuteCommon Patterns
Section titled “Common Patterns”Dedicated Test Inbox
Section titled “Dedicated Test Inbox”let testInbox;
beforeAll(async () => { testInbox = await client.createInbox({ ttl: 7200 }); // 2 hours});
afterAll(async () => { await testInbox.delete();});
test('password reset', async () => { await triggerPasswordReset(testInbox.emailAddress); const email = await testInbox.waitForEmail({ timeout: 10000 }); // ...});Multiple Inboxes
Section titled “Multiple Inboxes”const user1Inbox = await client.createInbox();const user2Inbox = await client.createInbox();const adminInbox = await client.createInbox();
// Each inbox receives emails independentlyawait sendWelcomeEmail(user1Inbox.emailAddress);await sendWelcomeEmail(user2Inbox.emailAddress);await sendAdminReport(adminInbox.emailAddress);Inbox Pool
Section titled “Inbox Pool”class InboxPool { constructor(client, size = 5) { this.client = client; this.pool = []; this.size = size; }
async initialize() { for (let i = 0; i < this.size; i++) { const inbox = await this.client.createInbox(); this.pool.push(inbox); } }
get() { return this.pool.shift(); }
async cleanup() { await Promise.all(this.pool.map((inbox) => inbox.delete())); }}Troubleshooting
Section titled “Troubleshooting”Inbox Not Receiving Emails
Section titled “Inbox Not Receiving Emails”Check:
- Email is sent to correct address
- Inbox hasn’t expired
- DNS/MX records configured correctly
- SMTP connection successful
// Verify inbox still existsconst emails = await inbox.listEmails(); // Will error if inbox expiredInbox Already Exists Error
Section titled “Inbox Already Exists Error”When requesting a specific email address:
try { const inbox = await client.createInbox({ });} catch (error) { if (error instanceof InboxAlreadyExistsError) { // Address already in use, generate random instead const inbox = await client.createInbox(); }}Inbox Expired
Section titled “Inbox Expired”try { const emails = await inbox.listEmails();} catch (error) { if (error instanceof InboxNotFoundError) { console.error('Inbox has expired'); // Create new inbox const newInbox = await client.createInbox(); }}Next Steps
Section titled “Next Steps”- Email Objects - Learn about email structure
- Managing Inboxes - Common inbox operations
- Import/Export - Advanced inbox persistence
- API Reference: Inbox - Complete API documentation