MOLTED EMAIL

Inbound Webhook Mappings

Connect external services like Clerk, Stripe, and Supabase to Molted Email without writing code.

Inbound webhook mappings let you receive webhooks from external services and automatically route data into Molted features -- sync contacts, subscribe to lists, or trigger journeys. No code required.

How it works

  1. Create an inbound webhook mapping in Molted
  2. Get a unique webhook URL (e.g., https://api.molted.email/v1/hooks/ink_abc123...)
  3. Paste that URL into your provider's webhook settings
  4. Configure where the email lives in the payload, field mappings, and actions

When the provider sends a webhook, Molted extracts the email address, maps fields, and executes your configured actions.

Creating a webhook mapping

Via CLI

molted inbound-hooks create \
  --name "Clerk Signups" \
  --source clerk \
  --email-path "data.email_addresses[0].email_address" \
  --field-map "name=data.first_name" \
  --field-map "clerkId=data.id" \
  --action "sync_contact" \
  --action "subscribe_to_list:lst_abc"

Via API

POST /v1/agent/inbound-hooks
{
  "name": "Clerk Signups",
  "source": "clerk",
  "emailPath": "data.email_addresses[0].email_address",
  "fieldMappings": {
    "name": "data.first_name",
    "clerkId": "data.id"
  },
  "actions": [
    { "type": "sync_contact" },
    { "type": "subscribe_to_list", "listId": "lst_abc" }
  ]
}

The response includes a urlToken field. Your webhook URL is:

https://api.molted.email/v1/hooks/{urlToken}

Email path syntax

The emailPath field uses dot notation with array index support to extract the email address from any JSON payload structure:

ProviderEmail path
Clerkdata.email_addresses[0].email_address
Stripedata.object.email
Supabase Authrecord.email
CustomAny valid dot-notation path

Field mappings

Map fields from the incoming payload to contact metadata:

{
  "name": "data.first_name",
  "company": "data.organization.name",
  "plan": "data.metadata.plan"
}

Mapped fields are stored as contact metadata and passed to list subscriber metadata.

Action types

Actions execute sequentially in the order configured.

ActionDescriptionParameter
sync_contactUpsert contact with mapped fieldsNone
subscribe_to_listAdd contact to a listlistId (required)
trigger_journeyFire an event to start a journeyeventName (required)

If an action fails, subsequent actions still execute. Failed actions are logged but don't block the webhook response.

Managing webhooks

# List all inbound webhook mappings
molted inbound-hooks list

# Get details for a specific webhook
molted inbound-hooks get <id>

# Update a webhook (e.g., disable it)
molted inbound-hooks update <id> --enabled false

# Delete a webhook
molted inbound-hooks delete <id>

# View recent delivery logs
molted inbound-hooks logs <id>

Security model

This MVP does not perform provider-side signature verification (Svix, HMAC, etc.). The receiver endpoint is authenticated by the URL token alone -- anyone with the URL can trigger the configured actions. Treat tokens as secrets:

  • Paste the URL directly into the provider dashboard; avoid logging or committing it
  • If a URL leaks, delete and recreate the webhook mapping to rotate the token
  • Per-token rate limit: 120 requests per 60 seconds. Excess deliveries receive 429

Signature verification is tracked as a post-MVP enhancement.

Delivery logs

Each webhook delivery is logged with:

  • Timestamp and source IP
  • Processing status (processed, partial, failed, rejected)
  • Per-action execution results
  • Error messages for failed actions
molted inbound-hooks logs <id> --limit 10

Provider setup examples

Clerk

  1. Create the webhook mapping:
    molted inbound-hooks create \
      --name "Clerk user.created" \
      --source clerk \
      --email-path "data.email_addresses[0].email_address" \
      --field-map "name=data.first_name" \
      --action "sync_contact" \
      --action "subscribe_to_list:<your-list-id>"
  2. In the Clerk Dashboard, go to Webhooks and add a new endpoint
  3. Paste your Molted webhook URL
  4. Subscribe to the user.created event

Stripe

  1. Create the webhook mapping:
    molted inbound-hooks create \
      --name "Stripe customer.created" \
      --source stripe \
      --email-path "data.object.email" \
      --field-map "name=data.object.name" \
      --field-map "stripeId=data.object.id" \
      --action "sync_contact"
  2. In the Stripe Dashboard, go to Developers > Webhooks
  3. Add your Molted webhook URL
  4. Select the customer.created event