Inbound email API · processed in the EU

Inbound email for your product.

Give each customer or workflow its own address. Every email arrives at your webhook as signed JSON.

100 emails/month free · no credit card

Webhook log
Toinvoices+acme@yourapp.com

+0msreceived from billing@supplier.eu "Invoice 1042"

+27msverified SPF ✓ DKIM ✓ DMARC ✓ spam 0.2

+58msrouted invoices@ → /inbound, tag "acme"

+182msPOST /inbound 200 OK · signed

{
  "message": {
    "recipient": { "email": "invoices+acme@…", "tag": "acme" },
    "subject": "Invoice 1042",
    "attachments": [{ "filename": "invoice-1042.pdf" }]
  },
  "spam": { "score": 0.2 }
}
  • invoices@
  • support@
  • orders@
Webhook payload

Pristine data, every field accounted for

No guesswork, no half-parsed HTML. Every email becomes a structured JSON payload with sender info, content in multiple formats, attachments, spam scoring, and much more.

POST /your-webhook — 200 OK
{
  "message": {
    "sender": {
      "name": "Alice Martin",
      "email": "alice@acme.com"
    },
    "recipient": {
      "name": null,
      "email": "invoices+acme@yourcompany.com",
      "tag": "acme"
    },
    "subject": "Invoice #1042 — February 2026",
    "content": {
      "text": "Hi, please find the invoice attached...",
      "html": "<p>Hi, please find the invoice...</p>",
      "markdown": "Hi, please find the invoice attached...",
      "links": [
        { "url": "https://acme.com/pay/1042", "domain": "acme.com", "anchorText": "Pay now" }
      ]
    },
    "attachments": [
      {
        "filename": "invoice-1042.pdf",
        "contentType": "application/pdf",
        "size": 48210,
        "status": "completed",
        "downloadUrl": "https://app.emailconnect.eu/attachments/9f8e7d6c/download",
        "virusScan": {
          "status": "clean"
        }
      }
    ]
  },
  "spam": {
    "score": 0.2,
    "engine": "rspamd",
    "authentication": {
      "dkim": { "result": "pass" },
      "spf": { "result": "pass" },
      "dmarc": { "result": "pass" }
    }
  },
  "classification": {
    "type": "normal",
    "confidence": "definite",
    "signals": [
      { "header": "return-path", "value": "alice@acme.com" }
    ]
  },
  "integrity": {
    "contentHash": "a3f2b8c1d4e5f6a7b8c9d0e1f2a3b4c5...",
    "rawEmailHash": "9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c..."
  }
}
Up to three content formats

Every email body arrives as plain text and raw HTML on every plan. Server-side Markdown conversion is available on Maker+ — switch it on per alias (it's off by default). Use whichever fits your pipeline.

Route on +tags

Mail to invoices+acme@ lands on your invoices@ alias with recipient.tag set to "acme". One alias, one endpoint, unlimited routing keys.

Attachments, handled

Small files inline as base64 (up to 2 MB on paid plans, 128 KB on Free). Larger files are offloaded to EU-hosted S3 and delivered as a downloadUrl that points at EmailConnect, so downloads stay counted and in-region. The whole email, attachments included, must fit within 10 MB.

Verified at every layerMaker+

Spam analysis, DKIM, SPF, and DMARC results included so you can filter and trust incoming e-mail.

Virus scanned attachmentsBusiness+

Every attachment scanned by ClamAV before delivery. Infected files are rejected and flagged in the payload.

Build your own payloadBusiness+

Pick exactly which fields you need. Strip what you don't. Per-alias payload configuration for complete control.

Data residency modePlatform

E-mail is processed in the region you choose. We store routing metadata only — not content.

Need anything? We're one email away.

Retried until it lands

Up to 7 attempts over about 22 hours, within your retention window.

Delivery and retries →

Signed, so you can trust it

Every delivery signed following Standard Webhooks, verifiable in a few lines.

Webhook signing →

One ID per email

The same ID on every retry and replay, so duplicates are easy to drop.

Deduplicating deliveries →
Integration

If it can receive a POST, it works

Webhook handlers in any language, no-code platforms, the API, or your AI agent. Pick whichever fits your stack.

// Express webhook handler (Standard Webhooks)
import express from 'express'
import crypto from 'crypto'

app.post('/webhook', (req, res) => {
  // Verify Standard Webhooks signature
  const { 'webhook-id': id, 'webhook-timestamp': ts, 'webhook-signature': sigs } = req.headers
  const secret = Buffer.from(process.env.WEBHOOK_SECRET.replace(/^whsec_/, ''), 'base64')
  const expected = crypto.createHmac('sha256', secret)
    .update(`${id}.${ts}.${req.rawBody}`).digest('base64')

  const valid = sigs.split(' ').some(s => s === `v1,${expected}`)
  if (!valid) return res.status(401).end()

  const { message } = req.body
  console.log(`From: ${message.sender.email}`)
  console.log(`Subject: ${message.subject}`)

  res.status(200).json({ received: true })
})
Why EmailConnect

Built to pass the review your customers will run

Your product takes in your customers' email. Where it goes, who can read it and what else we do with it become your answers too.

Processed only in the EU

  • EU companies only: Hetzner, Scaleway
  • No US company in the processing chain
  • DPA on every plan, Free included
  • Data Residency Mode on Platform
Trust center →

Inbound is all we do

  • Not a side feature of a sending platform
  • Catch-all, +tags and alias rules
  • Attachments, auth results, spam score
  • Signed, retried, deduplicated
How we compare →

What we won't do

  • Ask for access to your mailbox
  • Run AI on your customers' email
  • Build profiles from what we process
  • Keep it longer than you choose
Privacy promise →

Building a platform? See how one domain serves every customer

Testimonials

Trusted by teams across Europe

From e-commerce to public sector — teams rely on EmailConnect for secure, predictable email automation.

Before you start

What developers ask us first

Do I have to change my domain's MX records?

No, you can start on a ready-made address at @user.emailconnect.eu, which needs no DNS changes at all. To receive on your own domain, add one MX record and one TXT verification record. Using a subdomain such as in.yourdomain.com keeps your existing mailbox untouched.

Choosing a subdomain →
What happens if my endpoint is down?

Delivery is retried automatically, up to 7 attempts over about 21.6 hours (after roughly 1 minute, 5 minutes, 30 minutes, 2 hours, 12 hours and 7 hours). Retries stop when the message's retention window ends, so Free and Maker, with 1-hour retention, get up to 4 attempts. Every attempt carries the same webhook-id, so your handler can deduplicate.

Retry schedule →
How do I know a webhook really came from EmailConnect?

Every webhook is signed with the Standard Webhooks scheme (HMAC-SHA256), so any Standard Webhooks library can verify it in a few lines. Reject requests with an invalid signature or a timestamp older than five minutes. Signing is available on every plan, Free included.

Verifying signatures →
How are attachments delivered?

Documents, images and text files come inline as base64 in the JSON, up to 128 KB per file on Free and 2 MB on paid plans. On Maker and above, larger files up to 10 MB are stored in EU-hosted S3 and the payload contains a download link instead. Business can also store them in its own S3-compatible bucket.

Attachment options →
Where is my email processed, and how long is it kept?

Email is received and processed in Germany (Hetzner), and stored attachments live in France (Scaleway). Messages and their stored attachments are deleted automatically after your retention window: 1 hour on Free and Maker, 24 hours by default on Business (configurable up to 30 days). A data processing agreement is available on every plan, including Free.

Data processing agreement →

Comparing with SendGrid, Mailgun or Postmark? See how inbound handling differs

Our philosophy

We deliver your data. You decide what happens next.

No AI in our pipeline. Clean, verified email data at your endpoint, for your own code, workflows and agents.

Read our vision

100 emails/month free — no credit card