Give an agent its own email address for sending and receiving — verification codes, notifications, account registration, and autonomous inbox monitoring.
curl, jq, and node available on the servertext
External Sender
↓
[Resend Inbound]
↓ (webhook: email.received)
[Express /api/inbound-email]
↓ (save as JSON)
[mail/inbox/]
↓ (cron: every 5 min)
[Agent reads + processes]
↓
[Agent responds/acts]
If the domain isn't already verified:
bash
RESEND_KEY="re_xxxxx"
# Add domain
curl -s -X POST -H "Authorization: Bearer $RESEND_KEY" \
-H "Content-Type: application/json" \
https://api.resend.com/domains \
-d '{"name": "yourdomain.com", "region": "us-east-1"}'
# Get DNS records to configure
curl -s -H "Authorization: Bearer $RESEND_KEY" \
https://api.resend.com/domains/yourdomain.com | jq '.records'
Add the returned DNS records (TXT, MX, CNAME) to your DNS provider. Wait for verification (usually minutes).
Verify status:
bash
curl -s -H "Authorization: Bearer $RESEND_KEY" \
https://api.resend.com/domains/yourdomain.com | jq '{status, capabilities}'
Both sending and receiving must be "enabled".
Create routes/inboundEmail.js in your Express backend (see references/inboundEmail.js for full implementation). Key requirements:
/api/inbound-emailRESEND_WEBHOOK_SECRETmail/inbox/Mount in your server:
js
const inboundEmailRoutes = require('./routes/inboundEmail');
app.use('/api/inbound-email', inboundEmailRoutes);
bash
curl -s -X POST -H "Authorization: Bearer $RESEND_KEY" \
-H "Content-Type: application/json" \
https://api.resend.com/webhooks \
-d '{
"endpoint": "https://yourdomain.com/api/inbound-email",
"events": ["email.received"],
"enabled": true
}' | jq '{id, signing_secret}'
Save the signing_secret — you'll need it for webhook verification.
Add to your secrets management:
json
{
"RESEND_API_KEY": "re_xxxxx",
"RESEND_WEBHOOK_SECRET": "whsec_xxxxx",
"AGENT_EMAIL": "agent@yourdomain.com"
}
bash
mkdir -p mail/inbox
touch mail/inbox/.lastcheck
Create a cron job that checks for new emails every 5 minutes and notifies the agent:
text
Every 5 min → Check mail/inbox/ for new .json files
→ If new emails: read, summarize, and report to owner
→ Mark processed with .processed extension
Send a test email:
bash
curl -s -X POST -H "Authorization: Bearer $RESEND_KEY" \
-H "Content-Type: application/json" \
https://api.resend.com/emails \
-d '{
"from": "Agent <agent@yourdomain.com>",
"to": ["owner@theirdomain.com"],
"subject": "Email system test",
"text": "This is a test from my new email address."
}'
Verify receiving:
bash
curl -s https://yourdomain.com/api/inbound-email | jq .
Verify inbox:
bash
ls -la mail/inbox/
js
async function sendEmail(to, subject, text, html) {
const res = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${RESEND_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'Agent <agent@yourdomain.com>',
to: [to],
subject,
text,
...(html && { html }),
}),
});
return res.json();
}
js
async function getInbox() {
const res = await fetch('http://localhost:PORT/api/inbound-email');
const data = await res.json();
return data.emails;
}
async function getEmail(id) {
const res = await fetch(`http://localhost:PORT/api/inbound-email/${id}`);
return res.json();
}
async function ackEmail(id) {
await fetch(`http://localhost:PORT/api/inbound-email/${id}/ack`, { method: 'POST' });
}
Resend signs webhooks with HMAC-SHA256. Verify to prevent spoofing:
js
const crypto = require('crypto');
function verifySignature(rawBody, signature, secret) {
try {
const [timestamp, hash] = signature.split(',').map(s => s.trim());
if (!timestamp || !hash) return false;
const signedPayload = `${timestamp}.${rawBody}`;
const expected = crypto.createHmac('sha256', secret)
.update(signedPayload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(expected));
} catch {
return false;
}
}
RESEND_API_KEY or RESEND_WEBHOOK_SECRET in chat or logsProblemSolutionDomain not verifyingCheck DNS records propagated ( dig TXT yourdomain.com)Webhook not firingVerify webhook is enabled and endpoint is HTTPSSignature mismatchEnsure you're using raw body, not parsed JSONEmails not arrivingCheck domain receiving capability is enabledBackend not receivingCheck Express route is mounted before body parsers