# resendld: OpenClaw Resend inbound daemon — poll, hooks/agent, Caddy UI

Source: https://www.michaelchurley.com/blog/resend-listening-daemon-openclaw-poll-hooks-agent-caddy  
Published: 2026-03-27  
Author: Michael C. Hurley  
Tags: resend-listening-daemon, resendld, resend, openclaw, daemon, email, bun, typescript, convex, tanstack-start, caddy, hooks, telegram, macos, arch-linux, michaelmonetized

## Who

I needed inbound Resend mail to wake an OpenClaw agent on my machines. Local gateway path, readable UI, no SaaS inbox product.

For operators wiring Resend receiving boxes into a local agent gateway with a readable UI.

## What

I built **resendld**, public [`michaelmonetized/resend-listening-daemon`](https://github.com/michaelmonetized/resend-listening-daemon). HEAD `4fbec17`. **46** commits. Version **0.0.0-rc.0**.

![Architecture](/blog/resend-listening-daemon-openclaw-poll-hooks-agent-caddy/screenshots/architecture-stack.png)

`src/daemon/listen.ts` polls `https://api.resend.com/emails/receiving` every **5 seconds** with pure `fetch()` (no Resend CLI). List has no body. Each new id hits `/emails/receiving/{id}`, strips HTML if text empty, writes markdown under `~/.openclaw/workspace/mail/`, mirrors to Convex, then `POST`s OpenClaw `https://localhost:18789/hooks/agent` (TLS self-signed allowed). 404/401 falls back to `openclaw cron add --system-event`.

![Hooks dispatch](/blog/resend-listening-daemon-openclaw-poll-hooks-agent-caddy/screenshots/hooks-dispatch.png)

Web: TanStack Start **1.82.1** + Convex inbox/detail/boxes/reply at **https://resendld.localhost** behind Caddy. `install.sh` (640 LOC) targets macOS launchd + Arch systemd.

Afternoon of Mar 23 is mostly PATH hell against `resend-cli` across machines: try API, revert to CLI, then land pure fetch at `28041eac`. Tip #9 resolves `openclaw` cross-platform; ack path in `gateway.ts` still hardcodes `/Users/michael/.bun/bin/openclaw`.

![Web inbox](/blog/resend-listening-daemon-openclaw-poll-hooks-agent-caddy/screenshots/web-inbox.png)

## Where

Code: [github.com/michaelmonetized/resend-listening-daemon](https://github.com/michaelmonetized/resend-listening-daemon), public. No public deploy.

```bash
cd ~/Projects/resend-listening-daemon
bash install.sh          # or --dry-run / --force / --uninstall
# edit ~/.config/resendld/boxes.json
resendld start           # daemon + Convex + web :3000 + Caddy
# opens https://resendld.localhost
```

## When

**2026-03-23.** Phase 0, Telegram/Convex, ~20 PATH/CLI commits, `/hooks/agent`, pure fetch `28041eac`.

**2026-03-24.** Install/docs macOS+Arch (#3).

**2026-03-25.** HTML body fallback + web startup.

**2026-03-26.** TanStack Start pin to 1.82.1 (#8).

**2026-03-27.** Openclaw path (#9), HEAD `4fbec17`. Queue pushed_at 2026-03-27T23:11:34Z.

![Commit arc](/blog/resend-listening-daemon-openclaw-poll-hooks-agent-caddy/screenshots/commit-arc.png)

## Why

An agent that cannot receive email instructions is half-deaf. Poll Resend yourself, store locally, wake the gateway. Skip waiting on a webhook you do not control.

**Engagement Q:** Keep the 5s poll + seen-ids file, or move the tip to Resend webhooks into the same `/hooks/agent` path?
