Amazon SES Inbound Email Parsing: Extract Fields to JSON

Last updated August 2026

Try it now: extract email data to Excel, CSV, or JSON

Convert your email files
No install

Connect a mailbox to pull .eml/.msg in bulk, or paste a raw email to test the converter now.

or paste an email to test
Output format
Columns to extract
Extract your own custom fields
Popular:

Create a free account to download. No credit card required.

Don't want to write and maintain a MIME parser in Lambda?

Amazon SES hands you the raw email; pulling out the order number, invoice total, or customer name is still your code. MailParse returns clean, named fields and structured JSON straight from your inbox. See the email parser API, or follow the SES setup below first.

Amazon SES is best known for sending email, but it can also receive it. Point an MX record at SES, write a receipt rule, and every message to your domain can be stored in S3, handed to a Lambda function, or published to an SNS topic. It is solid, cheap infrastructure. The part that catches teams out is what SES hands over: the raw, unmodified email in MIME format. SES does not pull out the invoice total, the tracking number, or the lead's phone number. That parsing step is yours to build and keep working. This guide walks through how SES email receiving works, how to set it up, what you actually receive, and where the line sits between what AWS does and what you have to write.

Does Amazon SES support inbound email?

Yes. Amazon SES supports inbound email receiving in addition to sending. You configure a domain to route mail through SES, define receipt rules that decide what happens to each message, and SES then delivers the email to S3, invokes a Lambda function, or publishes it to an SNS topic. It has supported inbound receiving since 2015 and is widely used for building email-driven applications.

What SES does not include is any interpretation of the message. It moves the email to where your code can reach it, but the meaning of the content, the fields a human would read off the page, is left entirely to you.

How does Amazon SES email receiving work?

SES email receiving works by accepting mail for your domain and running it through a set of receipt rules that trigger actions. You point your domain's MX record at an SES inbound endpoint, and when a message arrives, SES evaluates your active rule set and performs the actions you defined, such as deliver to S3, invoke Lambda, or publish to SNS.

The most common production pattern is store-then-process: a receipt rule writes the full raw email to an S3 bucket, then triggers a Lambda function. The Lambda reads the message ID, fetches the raw MIME object from S3, and parses it. SES delivers the email exactly as it arrived, in MIME format, with nothing stripped or reformatted, so your parser sees the real headers, bodies, and attachments.

How do I set up Amazon SES to receive email?

Setup is three steps: verify the domain, add an MX record, then create a receipt rule. First, verify your domain in SES so it is allowed to receive mail. Second, add an MX record for the receiving hostname pointing at the SES inbound endpoint for your region, for example "10 inbound-smtp.us-east-1.amazonaws.com". Third, in the SES console create a receipt rule with one or more actions, typically deliver to an S3 bucket and invoke a Lambda function.

Two things save time. Use a dedicated subdomain such as inbound.example.com for receiving so you do not disturb your main domain's mail flow. And give SES permission to write to your S3 bucket and invoke your Lambda through the right bucket policy and resource permissions, which is the step most first-time setups miss.

What does an Amazon SES inbound email look like?

An SES inbound email arrives as raw MIME, the same multi-part text format an email client receives over SMTP. When stored in S3 the object is the complete message: headers, a plain-text part, an HTML part, and any attachments encoded inline. There is no JSON, no named fields, just the raw email. A simplified version looks like this:

From: "Acme Orders" <[email protected]>
To: [email protected]
Subject: Order #10482 confirmed
Content-Type: multipart/mixed; boundary="b1"

--b1
Content-Type: text/plain
Hi Sam, your order #10482 for $129.00 ships Tuesday.
--b1
Content-Type: application/pdf; name="invoice.pdf"
Content-Transfer-Encoding: base64
JVBERi0xLjQKJ...   (the PDF, base64 encoded)
--b1--

Everything you want is in there, but the order number 10482 and the 129.00 total are still inside the text. Turning that into named fields means decoding the MIME structure, picking the right part, and matching the values out of the body, which is the work SES leaves to you.

How do I parse an inbound SES email from S3 in Lambda?

You parse it by fetching the raw object from S3 and running it through a MIME parser in your Lambda. When SES invokes Lambda after writing to S3, your function reads the message ID from the event, calls getObject on the bucket to retrieve the raw email, and feeds the bytes to an email-parsing library to split out the headers, bodies, and attachments.

From there you write the field-level logic yourself: regular expressions or string matching to find the order number, the amount, the dates, and any custom values you need. Every email layout and every sender variation you handle adds to that code, and it breaks whenever a sender changes their template. That maintenance burden, not the AWS plumbing, is the real cost of rolling your own inbound parser.

What is the Amazon SES inbound email size limit?

Amazon SES accepts inbound messages up to 40MB by default, including attachments. That is generous for most transactional mail. The important catch is the delivery method: if you receive the email through an SNS notification rather than S3, the maximum message size is 150KB, because that is the limit on the content SNS will carry.

The practical rule is to store to S3 for anything but the smallest messages. Write the full email to a bucket, then use the SNS notification or an S3 trigger only to tell Lambda which object to fetch. That pattern sidesteps the 150KB ceiling entirely while still letting you process the complete email.

Why does SES only give Lambda the headers and not the body?

SES does this on purpose to keep the Lambda event small. The data SES passes to a Lambda function includes metadata and several email headers, but it does not contain the body of the message. You use the metadata, specifically the message ID, to retrieve the full email content from your S3 bucket.

So a working flow almost always writes the email to S3 first and invokes Lambda second. The Lambda receives a compact event, reads the message ID, and pulls the complete raw message from S3 to parse. Expecting the body in the Lambda event directly is one of the most common SES inbound mistakes.

In which AWS regions is SES email receiving available?

SES email receiving is only available in a subset of AWS regions, so you must check the current email-receiving endpoints before you build. Whatever region you choose, every resource involved in receiving, except the S3 bucket, has to live in that same region, including your SNS topics, KMS keys, and Lambda functions.

Plan the region first. If you pick a region that does not support inbound receiving, or you scatter your SNS topic and Lambda across regions, the receipt rule will fail to deliver. Choosing one supported region for the whole pipeline avoids a frustrating class of configuration errors.

How do I extract specific fields from an SES inbound email?

You extract specific fields by parsing the raw MIME and then applying your own matching logic, or by passing the email to a service that does both. SES itself only delivers the raw message, so getting the invoice number, vendor, amount, or tracking number into named columns means writing and maintaining that extraction code in Lambda, or sending the message to a dedicated email parser.

A parser built for the job connects to the same mailbox or accepts the forwarded message, reads the body and HTML tables, and returns the exact fields you name as clean JSON, CSV, or an Excel row. If you want to see what structured output looks like, our guide to converting email to JSON shows the shape, the email to JSON tool lets you try it on a real message, and the email parser API returns it directly without any MIME-parsing code on your side.

What is the best alternative to building an SES inbound parser?

The best alternative is to let SES handle delivery and hand the extraction to a purpose-built email parser instead of writing it yourself. You keep SES for what it is good at, receiving mail cheaply and reliably, and skip the brittle part: the MIME decoding, the per-sender field matching, and the ongoing maintenance when layouts change.

With MailParse you connect Gmail, Outlook, or Microsoft 365, or forward messages to a parsing inbox, name the fields you want, and get structured data back as JSON, CSV, or Excel. There are no Lambda functions or regular expressions to maintain. If you are comparing approaches and tools, our guide to the best email parser walks through what to look for, and the SendGrid Inbound Parse webhook guide covers the same trade-off for a different provider, as does the Mailgun email parser alternative page if your inbound mail routes through Mailgun. When an inbound message carries a PDF invoice you need as a spreadsheet, you can also convert it directly with a PDF to Excel converter once the file is out of S3.

The bottom line

Amazon SES inbound email is excellent plumbing. It receives mail, stores the raw MIME in S3, and triggers your code, all at AWS prices. What it does not do is read the email. Every field you need, every attachment's contents, and every layout change is parsing work that lands on your team. If your inbound flow is one stable email type, building that in Lambda is reasonable. Across many senders and formats, a parser that returns named fields and clean email data in Excel or JSON removes the part of the project that never stops needing attention. The same trade-off applies to the other hosted receivers, which we cover in the SendGrid Inbound Parse alternative and Mailgun email parser alternative comparisons.