Tokenmail: inboxes
Email addresses for agents, on froogmail.com: an agent signs up for a service with one, then reads the one-time code or follows the verification link itself. They only receive; nothing can be sent from them. $2 per inbox a month, on a subscription of its own (no sandbox plan needed). See froog Tokenmail.
$ froog inbox create --username signup --name "acme trial" # prints signup-k3f9qz@froogmail.com (Stripe Checkout opens the first time)
$ froog inbox wait signup-k3f9qz@froogmail.com --code # waits for mail with a code, prints just the code
$ froog inbox wait signup-k3f9qz@froogmail.com --link --from acme # or the verification link
$ froog inbox messages signup-k3f9qz@froogmail.com # what arrived, newest first
$ froog inbox read signup-k3f9qz@froogmail.com msg_… # one message; --html, --raw
$ froog inbox list · billing · rm ADDRESS
# for the agent in a VM: attach one, and it's $FROOG_EMAIL there from the VM's next start
$ froog inbox create --sandbox my-vm # or: froog inbox attach ADDRESS my-vm · detach ADDRESS
$ CODE=$(froog inbox wait "$FROOG_EMAIL" --code) # inside my-vm
Each message comes with the one-time codes and verification links found in it, most likely first, so an agent doesn't have to parse mail. A code is 4 to 8 digits (123456, 123-456) or 6 to 8 capitals and digits, next to a word like "code" or "verify"; prices, years and phone numbers aren't codes. Footer links (unsubscribe, privacy, social) are left out. wait also counts mail from the last minute, so start it right after submitting the form; --subject filters too, --timeout is in seconds (default 300), and --json prints the whole message. Name an inbox by its full address, the part before @, or its id. Mail to name+anything@froogmail.com goes to name@froogmail.com.
Paying. Inboxes are seats on a Stripe subscription separate from your sandbox plan: no free tier, no trial. The first froog inbox create opens Checkout and waits until you've paid. After that, each new inbox uses a free seat or adds one, with the rest of the month charged at once. Delete an inbox and its seat stays paid until the period ends (a new inbox can use it); at the renewal you're billed for the inboxes you have, with no credit for removals. With none left, the subscription ends at the period's end. If a payment fails and the subscription lapses, mail to your inboxes is refused until it's paid. froog inbox billing shows seats, inboxes and the renewal; cancel or change the card in Manage billing (the Stripe customer portal).
In the dashboard. Tokenmail is a mailbox: your inboxes on the left (with unread counts), the open inbox's messages in the middle (sender, subject, a preview and the code), and the open message on the right, its code and verification link at the top and the mail below. HTML mail shows in a locked-down frame, with no scripts and no remote images, and its links open in a new tab. The page checks for new mail every 15 seconds. Copy an address, attach an inbox to a sandbox or delete it from the top of its message list.
In a VM. VMs don't get an inbox by themselves. Attach one (one per VM) and it's $FROOG_EMAIL there from the VM's next start. The key inside the VM reads only that inbox: a key limited to some sandboxes sees only their inboxes, and can't buy, create, change or delete inboxes. Deleting the VM detaches the inbox; it stays yours.
Only mail for an existing inbox is accepted; anything else is refused while the sender is still connected, so nobody gets a bounce from us later. Mail arrives over TLS when the sender supports it. Messages are kept 30 days. A deleted inbox's address is never given out again, so nobody receives a previous owner's codes.
Use them for services that allow it. Don't use them to create accounts in bulk, to get around a ban, or to get past a CAPTCHA: when a sign-up shows one, solve it yourself in the VM's desktop and let the agent carry on (see the acceptable use policy).
API: GET/POST /v1/inboxes ({username?, name?, sandbox?}; 402 inbox_payment_required without a subscription), GET/PATCH/DELETE /v1/inboxes/{inbox} (PATCH {name?, sandbox?}, "" detaches), GET /v1/inboxes/billing ({required, active, price_cents, seats, used, status?, period_end?}), POST /v1/inboxes/billing/checkout {quantity?} (a Checkout url), GET /v1/inboxes/{inbox}/messages?since=&limit= (without bodies), GET/DELETE /v1/inboxes/{inbox}/messages/{id} (with text and html), GET …/messages/{id}/raw (message/rfc822), and GET /v1/inboxes/{inbox}/wait?since=&after=&sender=&subject=&timeout=, which holds the request until a matching message arrives (up to 120 seconds) and answers {message}, null on timeout. Reading needs inbox.read, the rest inbox.write (making an inbox can add a paid seat). The SDKs have them as createInbox, waitForInboxMessage, getInboxBilling, buyInboxes and so on.