Integration

Know when something happens, the moment it happens

Register a URL. Pick the events you care about. We POST signed payloads to your endpoint in real-time — deliveries, bounces, inbound messages, all of it. Retries included.

How webhooks work

1

Register an endpoint

Give us a URL and optionally filter which events you care about. We generate an HMAC signing secret so you can verify every payload is authentic.

2

Events fire automatically

When something happens — an email is delivered, a reply comes in, a bounce fires — we POST the event to your endpoint within seconds.

3

Verify the signature

Every request includes an X-Molted-Signature header. Compute HMAC-SHA256 of the raw body with your secret and compare. One line of code.

4

We retry on failure

Non-2xx response or timeout? We retry with exponential backoff — up to 5 attempts over roughly 45 minutes. Check the delivery log if something looks off.

5

Debug with the CLI

Run molted webhooks listen to spin up a local server that receives events in real-time. No tunnel setup, no public URL needed during development.

Register an endpoint

POST /v1/me/webhooks

POST /v1/me/webhooks
{
  "url": "https://example.com/hooks/molted",
  "description": "Production webhook",
  "events": ["inbound.received", "delivery.bounced"]
}

{
  "id": "wh_abc123",
  "url": "https://example.com/hooks/molted",
  "secret": "whsec_k7x...",
  "events": ["inbound.received", "delivery.bounced"],
  "enabled": true
}

What your endpoint receives

Every delivery includes the event type, a unique delivery ID, and an HMAC signature you can verify in one line.

POST https://example.com/hooks/molted
X-Molted-Signature: sha256=9f3a...
X-Molted-Event: inbound.received
X-Molted-Delivery: del_789xyz

{
  "event": "inbound.received",
  "timestamp": "2026-03-22T10:00:00Z",
  "data": {
    "messageId": "msg_...",
    "from": "alice@example.com",
    "to": "inbox@yourdomain.com",
    "subject": "Re: Intro",
    "hasAttachments": true,
    "mailboxId": "mbx_abc123"
  }
}

Verify the signature

Compute HMAC-SHA256 of the raw request body using your endpoint secret. Compare against the X-Molted-Signature header. Use timing-safe comparison to prevent timing attacks.

const crypto = require('crypto');

function verifyWebhook(rawBody, signature, secret) {
  const computed = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  const expected = signature.replace('sha256=', '');
  return crypto.timingSafeEqual(
    Buffer.from(computed),
    Buffer.from(expected)
  );
}

Event types

Subscribe to all events or pick specific ones. Leave the events array empty to receive everything.

EventDescription
inbound.receivedNew inbound email stored
inbound.classifiedInbound email classified by content type
inbound.routedInbound email routed to a thread
delivery.sentEmail accepted by the provider
delivery.deliveredEmail delivered to recipient
delivery.bouncedEmail bounced (hard or soft)
delivery.complainedRecipient marked email as spam

What you get

Event Filtering

Subscribe to all events or pick the ones you need. Inbound only? Just bounces? Your endpoint only gets what it asked for.

HMAC Signatures

Every payload is signed with your endpoint's secret. Verify authenticity with a single HMAC-SHA256 check.

Automatic Retries

Failed deliveries retry with exponential backoff. Five attempts, spread across 45 minutes. No events silently dropped.

Delivery Log

Full history of every delivery attempt per endpoint: status codes, response bodies, timestamps. Debug without guessing.

CLI Management

Create, list, update, and delete webhooks from the terminal. Your agent can manage its own event subscriptions programmatically.

Local Dev Server

molted webhooks listen starts a local HTTP server and streams events to your terminal. See exactly what your production endpoint will receive.

Manage from the CLI

Register endpoints, check delivery logs, or spin up a local dev server that receives events in your terminal. No public URL needed during development.

# Register a webhook
$ molted webhooks create \
    --url https://example.com/hooks/molted \
    --events inbound.received,delivery.bounced

# Start a local dev server
$ molted webhooks listen --port 9876

  Webhook server listening on http://localhost:9876/webhook
  Registered temporary endpoint wh_tmp_... (events: all)
  Waiting for events... (Ctrl+C to stop)

  ── inbound.received ── 2026-03-22T10:05:00Z ──────
  { "messageId": "msg_...", "from": "alice@example.com" }

Push, don't poll

Real-time event notifications with HMAC signatures, automatic retries, and a full delivery log. Your agent reacts to events as they happen instead of polling for changes.