
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
Disposable email inboxes for end-to-end tests. Waits for the message instead of sleeping, and hands you the verification code already extracted.
Disposable email inboxes for end-to-end tests — with the verification code already extracted.
npm i inboxsink
Testing a signup flow means waiting for an email. Most test suites do this:
await page.click('#signup');
await page.waitForTimeout(5000); // 🤞
That is the single most common source of flaky CI. waitForMessage blocks until the
message actually lands — no polling loop, no guessed delay — and hands you the
verification code without parsing anything.
import { InboxSink } from 'inboxsink';
const sink = new InboxSink(process.env.INBOXSINK_API_KEY);
const inbox = await sink.createInbox();
// { id: '42', address: '9f2c1a@mailhusk.com', expiresAt: Date }
// ... trigger the email in your app ...
const code = await sink.waitForOtp(inbox.id, { timeoutMs: 45_000 });
// '204815'
import { test, expect } from '@playwright/test';
import { InboxSink } from 'inboxsink';
const sink = new InboxSink();
test('a new user can sign up', async ({ page }) => {
const inbox = await sink.createInbox({ ttlSeconds: 900 });
await page.goto('/signup');
await page.fill('#email', inbox.address);
await page.click('#submit');
const code = await sink.waitForOtp(inbox.id); // blocks until the mail arrives
await page.fill('#code', code);
await page.click('#verify');
await expect(page.getByText('Welcome')).toBeVisible();
await sink.deleteInbox(inbox.id);
});
const link = await sink.waitForLink(inbox.id);
await page.goto(link);
const [latest] = await sink.listMessages(inbox.id);
const full = await sink.getMessage(latest.id);
console.log(full.subject, full.text, full.html, full.attachments);
| Method | What it does |
|---|---|
createInbox({ domain?, prefix?, ttlSeconds? }) | New inbox. Everything is optional. |
waitForMessage(id, { timeoutMs?, since? }) | Blocks until a message arrives. null on timeout. |
waitForOtp(id, opts?) | Blocks, returns the code. Throws if none arrives. |
waitForLink(id, opts?) | Blocks, returns the confirmation link. |
listMessages(id, { since?, limit? }) | Summaries, newest first. |
getMessage(messageId) | Full message: text, html, headers, attachments. |
deleteInbox(id) | Deletes the inbox and its messages now. |
domains() | Domains available for new inboxes. |
waitForOtp throws rather than returning null when a message has no code — a test
should fail loudly instead of quietly submitting an empty field.
The code is only reported when the message actually announces one ("code", "verification", "sign in"…), so an invoice total or a year is never mistaken for one.
new InboxSink('ibsk_…'); // explicit key
new InboxSink(); // reads INBOXSINK_API_KEY
new InboxSink(key, { baseUrl: 'https://…' }); // self-hosted
new InboxSink(key, { fetch: myFetch }); // custom fetch
Get a key at inboxsink.com. The free tier includes 1 000 calls a month, no card.
Every failure throws InboxSinkError carrying status and code.
| Code | Meaning |
|---|---|
401 | Key missing, unknown or revoked |
403 | That inbox belongs to another key |
404 | Inbox or message gone (expired) |
429 | Too many calls |
These inboxes receive only — they cannot send. A message sent from a disposable domain is rejected or spam-filed by essentially every provider, so a "reply" button would be a button that does nothing.
Requires Node 18+ (uses the global fetch). Zero dependencies.
MIT
FAQs
Disposable email inboxes for end-to-end tests. Waits for the message instead of sleeping, and hands you the verification code already extracted.
We found that inboxsink demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.