Every webhook endpoint can receive email. Turn the inbox on and <subdomain>@otterkit.app starts accepting mail. Each message lands in the endpoint's feed as a capture with method EMAIL, next to the HTTP traffic. The body is a JSON envelope with from, to, subject, text, html, and attachment metadata, so forwarding rules, notifications, stored history, and replay all treat an email like any other request.
$ npx otterkit webhook --email
✓ Webhook ready
URL https://hook-e5f6g7h8.otterkit.app
Inbox [email protected]In the console, the endpoint header shows the inbox address with an on/off switch. The Email inbox tab is a full reader: a message list on the left and the rendered email (HTML or text) on the right, with headers and attachment details. Search covers subject and sender across everything stored.
For agents#
Agents often need to receive email: signup confirmations, one-time codes, magic links. Create the endpoint with webhook_create and email: true over MCP, give the address to the service that needs it, then call request_await to catch the message the moment it arrives. It is the same tool that waits for webhooks:
webhook_create { "subdomain": "signup-test", "email": true }
→ [email protected]
request_await { "subdomain": "signup-test", "method": "EMAIL" }
→ { "subject": "Your verification code", "text": "Code: 481-923", ... }From the terminal, the same flow is otterkit webhook --email --daemon followed by otterkit await <subdomain> --method EMAIL --count 1.
Bounces and limits#
Nothing is silently dropped. Mail is rejected at SMTP time, so the sender gets a normal bounce with the reason, when the inbox is off, the endpoint has expired or stopped, the address doesn't exist, or the message is larger than 5 MB.
Received emails count toward the endpoint's fair-use limit of 100,000 requests per 30 days. The stored envelope is capped at 64 KB: long messages are truncated, HTML first. Attachment contents are not stored, only their names, types, and sizes.