- 01Take the address above.
It already exists — nothing to create, nothing to confirm.
- 02Paste it
into whatever signup form is asking you for an email.
- 03The code shows up here
in large type with a copy button. You never have to open or read the message.
For your automated tests
The same service exposes an API. The route that matters is wait: it blocks until the message lands, instead of making you guess at sleep durations in your end-to-end tests.
- wait blocks until the email lands. No more
sleep()in your tests. - OTP and links come back already extracted, as plain JSON fields.
- Webhooks and a domain of your own on the Developer plan.
1,000 calls a month, no card asked. Enough to wire it into your test suite and see if it holds.
// Playwright — a whole signup, code included const { address, id } = await sink.createInbox(); await page.fill('#email', address); await page.click('#signup'); const code = await sink.waitForOtp(id); // unblocks when the mail arrives await page.fill('#code', code); // the code is already extracted
// cypress.config.js — setupNodeEvents on('task', { createInbox: () => sink.createInbox(), waitForOtp: (id) => sink.waitForOtp(id, { timeout: 45000 }), }); // signup.cy.js cy.task('createInbox').then(({ id, address }) => { cy.get('#email').type(address); cy.get('#signup').click(); cy.task('waitForOtp', id).then((code) => cy.get('#code').type(code)); });
import requests, os API = "https://inboxsink.com/v1" H = {"Authorization": f"Bearer {os.environ['INBOXSINK_API_KEY']}"} box = requests.post(f"{API}/inboxes", headers=H).json() driver.find_element(By.ID, "email").send_keys(box["address"]) msg = requests.get(f"{API}/inboxes/{box['id']}/wait", params={"timeout": 45000}, headers=H, timeout=55).json() code = msg["message"]["otp"] # '204815'
curl -X POST https://inboxsink.com/v1/inboxes \ -H "Authorization: Bearer $KEY" → { "id": "42", "address": "9f2c1a@mailhusk.com" } curl "https://inboxsink.com/v1/inboxes/42/wait?timeout=45000" \ -H "Authorization: Bearer $KEY" → { "message": { "otp": "204815", "link": "https://…/confirm" } }
Pricing
The disposable inbox stays free and account-free, forever. What you pay for is automation: the API, domains of your own, and how long things are kept.
- Instant disposable address
- Verification code extracted
- Kept for 1 hour
- Shared domain
- No API
- Full API, including wait
- 10,000 API calls / month
- 1 domain of your own
- Webhooks
- Kept for 30 days
Card payment handled by Stripe. Cancel in one click from your dashboard.
The free account includes an API key capped at a thousand calls a month, enough to evaluate without commitment. No card asked.
These inboxes receive, full stop. You cannot reply from a disposable address, and that is on purpose: such a message would not arrive anywhere anyway.
Remote images in messages are blocked by default. HTML is rendered in isolation, with no scripts and no access to the page.
The free inbox expires after one hour. The Developer API supports longer retention when you configure it.
Why pay for a custom domain?
Because signup forms refuse known disposable domains. A domain of your own is published nowhere, so it lands on no blocklist and your tests keep passing. It is the only durable way to make this kind of test hold up.
Can you reply from a disposable address?
No, and we would rather say so plainly than ship a button that does not work: a message sent from a disposable domain is rejected or spam-filed by nearly every provider. On a domain of your own, with your own reputation, that is another matter — write to us.
What happens to received mail?
It is deleted when the inbox expires: one hour on the free tier, up to thirty days depending on the plan. There is no archive and no backup beyond that.
Your next signup test can pass on the first try.
Start with a free API key. Upgrade when your tests need a custom domain or more capacity.
Use your own domain, webhooks and the API on the Developer plan — 29 € a month. Acceptance of an address is decided by each website.