Your AWS SES. Your dedicated Mailat. See how it works
Mailat Journal

n8nEmail automationAmazon SESAPIWebhooks

Automate Email with n8n and Mailat: An Amazon SES Guide

Automate email with n8n and Mailat using Amazon SES. Configure API sending, stable retry keys, incoming-mail webhooks and delivery-status workflows.

By Ibrahim Sherbeny7 min read
Connected paper tiles with envelopes, a clock and branching paths illustrate an automated email workflow.
In this article

A customer places an order. A receipt needs to go out. Someone replies with a question, and your team needs to know. These are small jobs individually—and excellent candidates for automation once they start repeating.

You can automate email with n8n and Mailat through Mailat's REST API and signed webhooks. Mailat sends through your AWS SES account, stores mail and exposes its status. n8n connects those actions to the rest of your workflow.

We will configure an outgoing message first, then look at the additional work needed for incoming-mail and delivery-event workflows.

How n8n, Mailat and Amazon SES fit together#

Your application event
    → n8n workflow
    → Mailat email API
    → Amazon SES
    → Recipient's mail server

Incoming mail or delivery feedback
    → Mailat signed webhook
    → Verified event processing
    → n8n workflow

This guide uses n8n's general HTTP Request and Webhook nodes. It does not require a dedicated Mailat node. The HTTP Request node supports calling REST APIs with configured credentials, headers and request bodies. n8n HTTP Request documentation

You are calling your Mailat installation, such as https://mail.example.com/api/v1. The website at mailat.co is not a shared sending endpoint for every installation.

Before you build the workflow#

You need:

  • A running Mailat installation reachable from n8n over HTTPS.
  • A verified sending domain and a sender your Mailat account may use.
  • AWS SES configured for the recipients and volume you intend to send to.
  • An API key with email:send; add email:read when you need status or incoming-message details.
  • An n8n workflow you can edit and a test recipient you control.

Create the key through an organization account with the necessary permissions. A mail-only mailbox user cannot create API keys. Start with narrow scopes rather than giving every workflow administration access.

For marketing, begin with people who requested the messages and preserve unsubscribe and suppression behavior. The SES opt-in article explains why a list of addresses is not enough.

Workflow 1: send a transactional email from n8n#

Start with a Manual Trigger and an HTTP Request node. Use a fixed test message before connecting real order or account events.

Configure the Mailat request#

Set the request to:

Setting Value
Method POST
URL https://mail.example.com/api/v1/emails
Authentication Generic credential using Header Auth
Credential header name Authorization
Credential header value Bearer YOUR_MAILAT_API_KEY
Body content type JSON
Additional header Idempotency-Key: receipt-order-1042-v1

Replace the example host, sender and recipient. Save the real key in an n8n credential, not in a body field or a shared workflow export. n8n HTTP credential documentation

Use this JSON body for the first test:

{
  "from": "[email protected]",
  "to": ["[email protected]"],
  "subject": "Your order 1042 is confirmed",
  "text": "Thanks for your order! We have received order 1042 and will let you know when it is ready.",
  "metadata": {
    "orderId": "1042"
  }
}

The addresses are placeholders; the test will only work after you replace them with an authorized sender and a reachable recipient. Plain text keeps the first run easy to inspect. You can add an HTML version or use Mailat templates after the basic request works.

Understand the retry key before turning on automation#

The idempotency key identifies one logical send. For this example, receipt-order-1042-v1 belongs to this particular order-confirmation message.

  • Use a different key for a different order or a deliberately new message.
  • Reuse the same key and identical payload when retrying the same message.
  • Store the key with the business event so a new n8n execution can reuse it.
  • Do not generate a fresh key from the current time on every attempt.

Mailat requires a key for sending. Keys are 8–128 characters, and using an existing key with changed content returns a conflict. This protects against a common problem: a workflow times out, retries, and sends the customer two receipts.

If you use n8n expressions to build the key from an order ID, keep the result stable across retries. Use structured JSON fields for customer data rather than assembling JSON or HTML by string concatenation.

Inspect the result#

Run the workflow once. A successful Mailat response uses the envelope code, message and data. The email response includes an ID and status; save the returned data.id with your order record.

When needed, request GET /api/v1/emails/{id} with an email:read key to inspect the send's current state. Replace {id} with that saved ID.

An API response is not proof that the message reached the inbox. queued, sent, delivered, failed and unknown represent different stages. A delivered status means the recipient's server accepted the message, not that it appeared in the primary inbox.

The current request and response contract is available from your installation at /api/v1/openapi.json, with examples in the Mailat automation guide.

Handle errors without duplicate sends#

Result Workflow behavior
400 Inspect the response for invalid input; fix the request instead of retrying unchanged forever.
401 or 403 Check the key, scopes and sender permissions.
409 Check whether the same idempotency key was reused with different content.
429 Respect Retry-After and keep the same key and payload.
Timeout or 500 Preserve the original key. Reconcile the send rather than starting a new logical message.
Mailat status unknown Investigate whether SES accepted it before deciding on any replacement send.

Keep the default distinction between successful and unsuccessful HTTP responses. If you change n8n's error-handling settings, make sure failures take an explicit branch rather than silently looking like success.

Workflow 2: react to incoming email#

An incoming message can trigger useful work elsewhere: create an internal task, record an inquiry in your CRM, or notify the person responsible for an address.

For this flow, first configure email receiving with Amazon SES. Then subscribe to Mailat's email.received event.

An event has this shape:

{
  "version": "1",
  "id": "stable-event-uuid",
  "type": "email.received",
  "createdAt": "2026-10-08T10:00:00Z",
  "data": {
    "messageUuid": "mailbox-message-uuid",
    "identityUuid": "receiving-identity-uuid"
  }
}

The event identifies the message; do not assume it contains the entire email. Fetch the current message through GET /api/v1/inbox/received/{uuid} using the event's messageUuid and an authorized email:read key. That key's owner must be allowed to read the message.

Verify the webhook before taking action#

Incoming webhook integration needs a verification step before you connect it to real business actions. This is additional work beyond the outgoing HTTP Request example.

Mailat sends an X-Webhook-Signature header containing a timestamp and HMAC signature. Your receiver must:

  1. Keep the exact raw request body.
  2. Calculate HMAC-SHA256 using the webhook secret over timestamp + "." + rawBody.
  3. Compare signatures in constant time and reject timestamps outside a five-minute tolerance.
  4. Validate the event version, ID and type.
  5. Store event IDs durably to avoid repeating an action after a retry or replay.

n8n's Webhook node offers test and production URLs and a Raw Body option. Use the production URL for a published workflow. Header authentication alone does not verify Mailat's HMAC. Implement the verifier in a suitable protected workflow step or a small receiver in front of n8n, following the Mailat webhook protocol. n8n Webhook documentation

Mailat requires public HTTPS webhook destinations and rejects private addresses and redirects. A localhost webhook is not a production destination.

Only acknowledge success after verified work has been durably accepted. If you immediately return success and later lose the workflow, Mailat cannot know it needs to retry. Track processing and completed states so retries can recover unfinished work without duplicating successful actions.

Workflow 3: follow delivery and bounce events#

Use the same verified receiver for email.delivered, email.bounced, email.complained or email.failed. Route each event to the appropriate internal action.

For example, a delivery event can update an order's notification record. A bounce can create a task to check the customer's contact details. Avoid a loop that responds to every delivery event by sending another copy of the same message.

Mailat retries webhook delivery and exposes failed deliveries for inspection and replay. Replay retains the event ID, which is why durable deduplication matters.

When to use Mailat's built-in automations#

If your workflow stays entirely inside email marketing—someone subscribes, receives a welcome message, waits, then receives a follow-up—Mailat's built-in automation builder may be enough.

n8n becomes useful when you need to coordinate several systems: your store, CRM, database, internal alerts and Mailat. Give each tool a clear job and avoid having both send the same welcome message.

For marketing sequences, use Mailat's campaign or automation pipeline and its consent checks. A transactional API call should not become a shortcut around unsubscribe handling.

Try one small workflow first#

Send one test message. Save its ID. Retry with the same key and payload, then inspect the record. Once that behaves as expected, connect your real trigger and add delivery monitoring.

Get Mailat on GitHub to run it yourself, or explore managed Mailat hosting from $15/month. Your n8n hosting and AWS usage are separate costs.