OpenClaw
Give your OpenClaw AI agent an inbox with MailBlastr — send reports, parse newsletters and receipts, and receive replies via signed webhooks, with a leveled security model.
This guide shows how to give an OpenClaw AI agent its own email inbox backed by MailBlastr — so it can send and receive mail with a dedicated address instead of borrowing your credentials.
Why give your agent an inbox?
An inbox lets your agent:
- Sign up for its own accounts on GitHub, hosting platforms, and more, so you never share your personal credentials.
- Process attachments such as receipts and invoices, and act on them.
- Receive newsletters, parse them, and forward the important parts to you.
- Send daily reports and digests.
- Send and receive email as a first-class capability.
Step 1: Get an API key
Create a MailBlastr API key for the agent from the dashboard — key creation is a human, signed-in step, so the agent cannot mint its own key (or widen the one you give it). Scope it to a dedicated domain if you want to sandbox the agent away from your production sending.
.env file, or put it in a password manager (e.g. a 1Password service account) the agent can read from its own vault.Step 2: Verify a domain
Your agent needs an address to send from and receive at. We strongly recommend a subdomain (agent.example.com) rather than the root domain, especially if you want to receive mail, so the agent’s sending reputation stays isolated from your primary domain.
- 1Add the domain
Create the subdomain via POST /domains or the dashboard, choosing the region closest to your agent.
- 2Add the DNS records
MailBlastr returns SPF, DKIM, and (for receiving) MX records. Add them at your DNS provider. See Managing domains.
- 3Enable receiving
If the agent should receive mail, enable inbound on the domain and add the MX record MailBlastr provides — not just sending records.
- 4Wait for verification
Verification usually completes within minutes (up to 72 hours for DNS to propagate). Poll GET /domains/:id until
statusisverified.
Once verified, store the address in the agent’s memory and have it send you a test email to confirm sending works.
Step 3: Receive email via webhooks
At this point the agent can send but not receive. To receive, register a webhook for the email.received event pointing at a public URL. During development, expose a local server with a tunnel such as Tailscale Funnel:
tailscale funnel 3000
# gives a stable public URL like https://hostname.tailnet-name.ts.netcurl -X POST 'https://www.mailblastr.com/api/webhooks' \
-H "Authorization: Bearer $MAILBLASTR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"endpoint": "https://hostname.tailnet-name.ts.net/api/webhook",
"events": ["email.received"]
}'A minimal handler verifies the signature, applies a sender allowlist, fetches the full inbound email, then notifies you:
import { Mailblastr, verifyWebhookSignature } from 'mailblastr';
const API_KEY = process.env.MAILBLASTR_API_KEY;
const WEBHOOK_SECRET = process.env.MAILBLASTR_WEBHOOK_SECRET; // 'whsec_...'
const mb = new Mailblastr(API_KEY);
// Security: strict allowlist
const ALLOWED_SENDERS = ['your@email.com'];
async function handler(req) {
// The raw body string — never a re-serialized JSON object, or the signature
// will not match.
const payload = await req.text();
// verifyWebhookSignature enumerates the object's own keys, so unpack a Fetch
// Headers instance into a plain object.
const headers = {
'svix-id': req.headers.get('svix-id'),
'svix-timestamp': req.headers.get('svix-timestamp'),
'svix-signature': req.headers.get('svix-signature'),
};
// Checks the HMAC and (by default) rejects a timestamp more than 5 minutes
// out. `reason` names the failure, e.g. 'no_match' or 'missing_headers'.
const { valid, reason } = verifyWebhookSignature(payload, headers, WEBHOOK_SECRET);
if (!valid) {
return new Response(`Invalid signature: ${reason}`, { status: 400 });
}
const event = JSON.parse(payload);
if (event.type === 'email.received') {
if (!ALLOWED_SENDERS.includes(event.data.from.toLowerCase())) {
return new Response('OK', { status: 200 }); // ignore, but ack
}
// Fetch the full inbound email with the SDK.
const { data: email } = await mb.emails.receiving.get(event.data.email_id);
await notifyUser(email);
}
return new Response('OK', { status: 200 });
}Step 4: Instant notifications via OpenClaw
Rather than polling its inbox on a cron, your agent can use OpenClaw’s Gateway API to be notified the instant MailBlastr delivers an email.received webhook — turning each inbound message into a real-time prompt. Wire your webhook handler to call the Gateway API, then send a test email to confirm the agent reacts immediately.
Security considerations
An agent inbox is powerful, and inbound email is an untrusted input — prompt injection via email is a real risk. MailBlastr signs every webhook so you can reject forged payloads, but you also need a policy for what the agent does with verified mail. Choose a security level and start strict:
- 1Strict allowlist
Only act on email from specific known senders. Recommended for most use cases.
- 2Domain allowlist
Act on email from any sender at a trusted domain (e.g. anyone at example.com).
- 3Content filtering with sanitization
Accept email from anyone, but sanitize the body to strip likely injection attempts before the agent reads it.
- 4Sandboxed processing
Process all email, but in a restricted context where the agent has limited capabilities and tools.
- 5Human-in-the-loop
Process all email but require human approval before the agent takes any action.