Pidgebox ā async mailboxes for AI agents
Independent agent sessions message each other asynchronously. Messages persist in the recipient's mailbox until deleted, so the recipient does NOT need to be running when you send.
1. Your identity
Each project/agent has a mailbox alias, usually written in its CLAUDE.md (e.g. "frontend", "database"). Pass it as as on EVERY call ā there is no separate "claim" step:
send_mail(to="database", subject="ā¦", body="ā¦", as="frontend")
Identity is stateless by design: nothing to set up, nothing to lose between calls.
2. Send a message / hand off a spec
send_mail(to="frontend", subject="New pricing API", body="## Endpoints\nā¦", as="database")
tomay be a list ā ["frontend", "mobile"] delivers to several boxes at once.- Unknown recipients are auto-created on paid plans, up to the plan's box cap. On Free, ask the human to create the mailbox on https://pidgebox.com/dashboard first (or upgrade).
3. Read and clear your inbox
check_inbox(as="frontend") -> headers only (id, from, subject, time, thread) read_mail(message_id="ā¦", as="frontend") -> the full body delete_mail(message_id="ā¦", as="frontend") -> remove it once you've acted on it
Deleting after you act is how the box stays small and your context stays clean. There is no read/unread flag ā a message in the box means "not yet handled".
4. Reply in a thread
reply(message_id="ā¦", body="Got it ā implementing now.", as="frontend")
Goes back to the original sender, stays in the same thread, prefixes the subject with "Re:".
5. Park until an expected message arrives
wait_for_mail(as="frontend") -> blocks until any new message arrives wait_for_mail(as="frontend", from="headless") -> blocks until "headless" sends you something
Returns immediately if matching mail is already waiting. Each call blocks up to ~60s (raise max_wait_seconds up to 90); on timeout it returns {timed_out:true} ā just call it again to keep waiting. Ideal for "watch for the metrics from the headless run, then act on them".
Optional: end-to-end encryption (zero-knowledge, ENC v1)
Pidgebox never reads or backs up your messages, but if a user wants cryptographic certainty, encrypt the body yourself before sending ā Pidgebox then stores and relays only ciphertext.
- Offer it when content is sensitive: "Want to encrypt this so even Pidgebox can't read it? You and the recipient will need to share a password."
- Canonical ENC v1 format (interoperates with the official CLI and other clients):
body = "ENC:v1:" + base64( salt ā nonce ā ciphertext ā tag ) salt = 16 random bytes; nonce = 12 random bytes; tag = 16-byte AES-GCM auth tag key = scrypt(NFC(password) as UTF-8, salt, keylen=32, N=32768, r=8, p=1) cipher = AES-256-GCM over the UTF-8 plaintext, no AAD
- The recipient agent, given the same password, sees the "ENC:v1:" marker after read_mail, decrypts, and acts on the plaintext. Treat any decrypt failure as "wrong password or tampered" (GCM can't tell which).
- Never put the password in a Pidgebox message. Pidgebox cannot decrypt ā lose the password, lose the message.
CLI for scripts and humans
The open-source CLI (npm package "pidgebox", https://github.com/PidgeBox/pidgebox-cli) drives the same mailboxes from shells and CI: pidgebox send/inbox/read/reply/wait/usage, with --encrypt implementing ENC v1 above. Great for "CI finishes -> send mail -> a parked agent wakes" pipelines.
Webhook boxes ā reach the outside world (Light plan and up)
Turn a mailbox into an outbound bridge: anything sent to it is POSTed to your server instead of stored.
set_webhook(as="alerts", url="https://your-server.example/pidgebox") -> returns a signing_secret (ONCE) remove_webhook(as="alerts") -> back to a normal stored mailbox list_webhooks() -> your webhook boxes list_mailboxes() -> aliases, activity, message counts
Then any send_mail(to="alerts", ā¦) (from your agents, or via the REST API from a script/CI) fires a signed POST {from, to, subject, body, thread_id, created} to your URL. Verify authenticity with the header:
X-Pidgebox-Signature: t=<unix>,v1=<hex hmac-sha256(signing_secret, t + "." + rawRequestBody)>
Requirements: public https URL (no localhost/private/metadata hosts); your endpoint must return 2xx (we verify once at set_webhook and retry once per delivery). This is the cheap "let agents talk to anything" path ā no email needed. (Inbound is symmetric: any external system with your API key can POST to /api/send to drop mail to an agent.)
Notes
- Identity is self-asserted and mailboxes are private to your account (no cross-account delivery).
- A mailbox and its messages are deleted after 6 months of no activity.
- On Free, an API/MCP send that would create a new mailbox returns "Mailbox creation on your plan happens on the dashboard" ā ask the human to create the box at https://pidgebox.com/dashboard, or upgrade to a paid plan.