DEV Community

René Bennekers
René Bennekers

Posted on

How to Turn Incoming Emails into JSON Webhooks (Without Running an SMTP Server)

Receiving incoming email in an application sounds simple—until you have to implement it.

Suppose you're building an automation, a SaaS application, or an internal tool. You want something to happen whenever an email arrives:

  • Create a support ticket.
  • Extract information from an incoming message.
  • Process an emailed document.
  • Trigger an automation workflow.
  • Store an email in your application's database.

Your application already accepts HTTP requests. Wouldn't it be convenient if incoming emails could arrive as JSON requests too?

The problem with receiving email

Sending email is relatively straightforward. Receiving it is another matter.

A traditional implementation may involve:

  • Configuring an SMTP server.
  • Managing DNS and MX records.
  • Receiving and parsing MIME messages.
  • Handling attachments and different character encodings.
  • Implementing delivery retries.
  • Maintaining the infrastructure.

For a small application, that's a lot of work when the actual requirement is simply to process an incoming message.

A simpler approach: Email → Webhook

Instead of having your application receive SMTP traffic, use a service that accepts the email and forwards it to your HTTPS endpoint as JSON.

The workflow becomes:

Someone sends an email
          |
          v
   SMTP email receiver
          |
          v
     Parse the email
          |
          v
   Create JSON payload
          |
          v
 POST to your webhook
          |
          v
    Your application
Enter fullscreen mode Exit fullscreen mode

Your application only needs to handle an ordinary HTTP POST request.

What does the webhook look like?

Here is an example based on an actual SMTP2Hook webhook delivery, with identifying information replaced:

{
  "event": "email.received",
  "message_id": "20261024113508891843",
  "received_at": "2026-10-24T11:35:08.891843+00:00",
  "mail_from": "sender@example.com",
  "rcpt_to": ["example123@smtp2hook.com"],
  "from": "Sender <sender@example.com>",
  "to": "example123@smtp2hook.com",
  "subject": "Hello from SMTP2Hook",
  "text": "This is a test email.\r\n",
  "attachments": [],
  "customer_id": "c_example",
  "endpoint_id": "example123"
}
Enter fullscreen mode Exit fullscreen mode

The important fields include:

  • event: Identifies the event type, in this case email.received.
  • message_id: Unique message identifier.
  • received_at: Timestamp indicating when the email was received.
  • mail_from / rcpt_to: SMTP envelope sender and recipient addresses.
  • from / to: Addresses extracted from the email headers.
  • subject: Email subject.
  • text: Plain-text email content.
  • attachments: Information about attachments, when present.
  • customer_id / endpoint_id: Identify the receiving customer and endpoint.

This is a real SMTP2Hook payload structure, with example values substituted for personal information.

Your application can extract the fields it needs and trigger the appropriate workflow.

Handling a webhook with Python

Here's a minimal example using Flask:

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.post("/email-webhook")
def email_webhook():
    payload = request.get_json(silent=True)

    if not isinstance(payload, dict):
        return jsonify({"error": "Invalid JSON"}), 400

    if payload.get("event") != "email.received":
        return jsonify({"error": "Unexpected event"}), 400

    print("Incoming email:")
    print("From:", payload.get("from"))
    print("Subject:", payload.get("subject"))
    print("Message:", payload.get("text"))

    return jsonify({"status": "received"}), 200


if __name__ == "__main__":
    app.run(port=5000)
Enter fullscreen mode Exit fullscreen mode

For demonstration purposes, this example receives the JSON payload and displays selected email fields.

A production webhook should also authenticate incoming requests, validate their contents, and handle processing failures appropriately.

If processing takes time, consider placing the event into a durable queue and returning HTTP 200 only after it has been safely accepted.

Also, a webhook destination must be publicly reachable for a hosted service to deliver events. A local Flask server listening on localhost:5000 is suitable for local testing but cannot be reached directly from the internet.

Introducing SMTP2Hook

I recently built SMTP2Hook to make this workflow simpler.

The idea is straightforward:

Email in. JSON out.

With SMTP2Hook, you can:

  1. Create an account.
  2. Create an email endpoint.
  3. Configure your webhook URL.
  4. Send an email to the generated SMTP2Hook address.
  5. Receive the email information as JSON at your webhook.

SMTP2Hook handles incoming SMTP messages and forwards them to the configured destination.

It also provides:

  • Delivery history.
  • Automatic webhook delivery retries.
  • Endpoint management.
  • A customer portal.
  • Support for email attachments.

You don't need to operate an SMTP server or configure your own MX records.

Getting started

SMTP2Hook is currently available as a public beta.

The FREE plan is permanently free and includes:

  • 1 email endpoint.
  • 50 incoming emails per month.
  • No credit card required.

You can try it here:

https://smtp2hook.com

Final thoughts

Not every application that processes email needs to operate an SMTP server.

For many integrations, transforming incoming email into an HTTP webhook is a simpler architecture.

I'd be interested to hear how other developers handle inbound email today.

Do you use IMAP polling, a managed inbound email service, your own SMTP infrastructure, or something else?

I'm particularly interested in feedback from developers building email-driven automations and backend integrations.


Disclosure: I'm the developer of SMTP2Hook. I built it to simplify inbound email integrations, and I'd welcome technical feedback from the DEV Community.

Top comments (0)