Back to App Store

Dead Simple Email

Dead Simple Email · io.pilot.deadsimple
An email identity your agent provisions for itself, then uses to send, receive, and read its own signup codes.
CommunicationsLive on catalogue
Install
pilotctl appstore install io.pilot.deadsimple
v0.1.0
Version
19
Methods
Size
shareable
Sandbox
macOS · Linux
Platforms

About Dead Simple Email

Dead Simple Email gives an agent a real, deliverable email identity — not a sandbox — and it can get one entirely on its own. A single call to deadsimple.signup returns an account, an API key and a live inbox. No dashboard, no verification email, no human in the loop.

The method agents reach for most is deadsimple.get_verification_code. It pulls the one-time code or magic link straight out of the newest inbound message, so an agent can sign itself up for a third-party service or clear a 2FA prompt without ever parsing an email body. Filter by sender and by timestamp so a stale code is never returned. This is what turns "the provider emails you a code" from a dead end into a step.

From there the agent sends, replies on-thread, reply-alls, forwards, reads full messages with headers and attachments, and walks whole conversation threads over one REST API.

Underneath is real sending infrastructure: DKIM-signed egress through a dedicated MTA, bounce and complaint handling, suppression lists, and optional open and click tracking. Inbound mail can be pushed to HMAC-SHA256 signed webhooks that retry on exponential backoff. A supervisor agent can watch every inbox in a workspace at once with list_all_messages, and inboxes can be created in bulk, tagged, and torn down when a throwaway identity is finished.

Tiers. A self-provisioned agent account starts on trial: 1 inbox, 10 sends an hour, 25 a day. Calling deadsimple.claim with an email a human controls, then deadsimple.claim_verify, moves it to the Free plan — 5 inboxes and 5,000 emails a month — keeping the same API key, inboxes and history. Paid plans scale to 500 inboxes, 25 custom domains, and 1,000 requests a minute.

Edge cases. A 429 with code trial_send_limit_exceeded is a quota signal, not a transient failure — do not blindly retry, claim the account instead. Pagination is cursor-based. Spam is excluded from list_messages unless include_spam is true. Delete throwaway inboxes when finished so they stop counting against the quota.

Methods · 19

deadsimple.signup
START HERE if you have no key. Provisions a Dead Simple account, an API key and a live inbox in one call, with no human, no dashboard and no verification email. Returns {account_id, api_key, inbox}. Save api_key as the DEADSIMPLE_API_KEY secret — every other method authenticates with it. Idempotent per Idempotency-Key, so a retry after a dropped connection returns the same account rather than a second one. The account starts on the trial tier: 1 inbox, 10 sends an hour, 25 a day.
deadsimple.claim
Start lifting the trial caps by attaching an email address a human controls. Sends a 6-digit code to that address; pass it to deadsimple.claim_verify to finish. Your existing API key, inboxes and message history are untouched by the upgrade.
deadsimple.claim_verify
Confirm the code from deadsimple.claim and move the account from trial to the Free plan (5 inboxes, 5,000 emails a month). The same API key keeps working.
deadsimple.create_inbox
Create a real, deliverable email inbox in one call. Returns an inbox_id and a live address that can send and receive immediately — no SMTP setup, no DNS, no mailbox provisioning. Use this when you already have a key and want an additional identity.
deadsimple.list_inboxes
List the inboxes this key can see, newest first. Cursor-paginated: pass the cursor from the previous response for the next page.
deadsimple.get_inbox
Fetch one inbox: its address, display name, tags, status, and counters.
deadsimple.delete_inbox
Permanently delete an inbox and its stored messages. IRREVERSIBLE. Use when a throwaway identity is finished so it stops counting against the inbox quota.
deadsimple.send_email
Send an email from one of your inboxes. Plain text or HTML, cc/bcc, base64 attachments, scheduled send, and optional open/click tracking. Real DKIM-signed egress, not a test harness. On the trial tier this is capped at 10 an hour and 25 a day; a 429 with code trial_send_limit_exceeded is a quota signal, not a transient failure.
deadsimple.get_verification_code
THE method agents reach for. Pulls the one-time code or magic link straight out of the newest inbound message, so a signup or 2FA prompt can be cleared without parsing an email body. Non-blocking: returns found=false if nothing has arrived, so poll every 2-3 seconds for up to a minute after triggering the mail. Set `since` to a timestamp taken BEFORE you triggered it, and `from_contains` to the sender domain, so a stale code is never returned.
deadsimple.list_messages
List messages in an inbox, newest first, with sender, subject, snippet, and labels. Spam is excluded unless include_spam is true. Cursor-paginated.
deadsimple.get_message
Get one message in full: headers, plain-text and HTML bodies, and attachment metadata.
deadsimple.reply
Reply to the sender of a message. Threading headers are set automatically so the reply lands in the same conversation — never hand-build In-Reply-To.
deadsimple.reply_all
Reply to the sender and every other recipient of a message, with threading headers set automatically.
deadsimple.forward
Forward a message, with its attachments, to new recipients.
deadsimple.list_threads
List conversation threads in an inbox, each with its latest message, so an agent can track ongoing exchanges instead of loose messages.
deadsimple.get_thread
Get a full conversation thread with every message in order — the context an agent needs before replying.
deadsimple.get_attachment
Get a time-limited signed download URL for an attachment. The link expires in one hour.
deadsimple.list_all_messages
List messages across every inbox this key can see, newest first. For a supervisor agent watching many identities at once — cheaper than iterating inboxes.
deadsimple.create_webhook
Register an HMAC-SHA256 signed webhook for inbound mail, bounces, and complaints, so long-running work does not have to poll list_messages in a loop. Deliveries retry on exponential backoff and every attempt is logged.

Full usage demo

When your agent needs an email address of its own: to sign itself up for a third-party service and read the code back, or to send and receive real mail as part of a task.

Run this first — Get an account, an API key and a live inbox in one call
Call
pilotctl appstore call io.pilot.deadsimple deadsimple.signup '{"label":"my-agent"}'
{"data":{"account_id":"...","api_key":"dse_...","inbox":{"inbox_id":"...","email":"[email protected]"},"plan":{"plan":"trial","inbox_limit":1,"sends_per_hour":10}}}

Everything is under data. Save data.api_key as DEADSIMPLE_API_KEY — it is shown once. Already have a key? Skip this and call create_inbox.

Worked examples

Sign up for a third-party service and read the code back
Call
pilotctl appstore call io.pilot.deadsimple deadsimple.get_verification_code '{"inbox_id":"<id>","since":"2026-08-06T12:00:00Z","from_contains":"stripe.com"}'
{"data":{"found":true,"code":"481920","magic_link":null,"message_id":"..."}}

Note the time BEFORE submitting your address, pass it as `since`, then poll every 2-3s. found=false just means it has not landed yet. Never parse the raw email yourself.

Send a real email
Call
pilotctl appstore call io.pilot.deadsimple deadsimple.send_email '{"inbox_id":"<id>","to":"[email protected]","subject":"Report ready","text_body":"The run finished."}'
{"data":{"message_id":"...","status":"queued"}}

DKIM-signed egress, not a sandbox. Trial caps this at 10/hour, 25/day.

Read a conversation before replying
Call
pilotctl appstore call io.pilot.deadsimple deadsimple.get_thread '{"inbox_id":"<id>","thread_id":"<tid>"}'
{"data":{"thread_id":"...","messages":[{"message_id":"...","from":"...","subject":"..."}]}}

Then reply with the message_id; threading headers are set for you.

Good to know

  • Every response is wrapped: the payload is under data, with meta.request_id beside it.
  • Call signup only when you have no key. It is idempotent per Idempotency-Key, so a retry returns the same account, not a second one.
  • Trial is 1 inbox, 10 sends/hour, 25/day. A 429 trial_send_limit_exceeded is a QUOTA signal, not transient — do not retry it.
  • Lift the caps with claim then claim_verify. Your key, inboxes and history survive.
  • get_verification_code needs since from BEFORE you triggered the mail, or you may read a stale code.

Next

  • io.pilot.deadsimple deadsimple.help '{}'

What’s New

v0.1.0Latest
  • First release on the Pilot app store.

Platform Compatibility

macOSApple Silicon
Supported
macOSIntel
Supported
Linuxarm64
Supported
Linuxamd64
Supported
You might also like

More in Communications