Email reply parser
Just the reply, never the thread under it
Every email that reaches AI Inbx is cut into what the sender wrote, what they quoted and their signature. stripped_text is the part that is new, answers typed inside the quote included.
Priya’s reply from Outlook, cut into segments.
- written
Hi Sam, answers below. - signature
Thanks,Priya NairOperations lead, Lumen Health+44 20 7946 0321
- quoted
From: Yourapp Support <support@mail.yourapp.com>Sent: Tuesday, September 22, 2026 10:14To: Priya Nair <priya@lumenhealth.com>Subject: RE: Ticket #4127: CSV export fails Hi Priya, Sorry the export failed. Three things will help us find it: Which browser are you on?
- written
Edge, latest version. - quoted
Does it fail for every date range? - written
Only for ranges longer than 90 days. - quoted
Roughly how many rows are in the export? - written
About 40,000. - quoted
Thanks,SamYourapp Support
What she wrote, as your code reads it.
Hi Sam, answers below. > Which browser are you on?Edge, latest version. > Does it fail for every date range?Only for ranges longer than 90 days. > Roughly how many rows are in the export?About 40,000.
Threads
Outlook marks nothing. The thread does.
Outlook quotes under a header block with no > on any line, so answers typed inside look like quote. When the message being answered is on the thread, each line copied from it is quote, and what is left is hers.
Threads- Hi Priya,in Sam’s message
- Sorry the export failed. Three things will help us find it:in Sam’s message
- Which browser are you on?in Sam’s message
- Edge, latest version.written
- Does it fail for every date range?in Sam’s message
- Only for ranges longer than 90 days.written
- Roughly how many rows are in the export?in Sam’s message
- About 40,000.written
- Thanks,in Sam’s message
- Samin Sam’s message
- Yourapp Supportin Sam’s message
Signatures
A signature once, not on every reply
The first time a sender signs on a thread, the signature stays in stripped_text: it is where their name, role and number are. Once an earlier mail of theirs carries it, it is dropped.
SignaturesHi, The CSV export on the Reports page has failed three times today.
Thanks,Priya NairOperations lead, Lumen Health+44 20 7946 0321kept
Hi Sam, answers below. > Which browser are you on?Edge, latest version.
…
Forwards
A forward keeps what it forwards
A forward, or a reply to mail sent before the inbox was connected, answers nothing on file, so its quote is new to the thread. That quote is the content, so stripped_text keeps it and segments still marks it as quoted.
ForwardsSam, this is the vendor thread I mentioned. Can you take it?
---------- Forwarded message ---------From: Marek Havel <marek@datagrid.cz>Date: Mon, 21 Sep 2026 at 16:02Subject: Export limitsTo: Priya Nair <priya@lumenhealth.com> Hi Priya, Exports over 25,000 rows are split into several files on our side. Marek
Clients
The quote starts differently in every client
Attribution lines in English, German, French, Spanish, Italian, Dutch, Portuguese and more, wrapped or not. Outlook’s header block, forward separators, and the quote markup of Gmail, Outlook, Apple Mail, Yahoo and Thunderbird.
Clients- On Tue, 22 Sep 2026 at 10:14, Sam <support@mail.yourapp.com> wrote:English
- Am 22.09.2026 um 10:14 schrieb Sam <support@mail.yourapp.com>:German
- Le mar. 22 sept. 2026 à 10:14, Sam <support@mail.yourapp.com> a écrit :French
- El mar, 22 sept 2026 a las 10:14, Sam (<support@mail.yourapp.com>) escribió:Spanish
- Il giorno mar 22 set 2026 alle ore 10:14 Sam <support@mail.yourapp.com> ha scritto:Italian
- Op di 22 sep 2026 om 10:14 schreef Sam <support@mail.yourapp.com>:Dutch
- Von: Yourapp Support <support@mail.yourapp.com>Outlook, German
- -------- Original message --------Separator
- Sent from my iPhoneSignature
Compared
How replies usually get stripped
Every approach below reads one message and guesses where the quote begins. That works for the reply typed above the quote, which is most of them. It breaks on the reply people send to a list of questions.
Set up
Three fields on every email
if (event.type === "email.received" && event.data.category === "human") { const email = event.data.email ?? (await aiinbx.emails.retrieve(event.data.email_id)) await tickets.comment(event.data.thread_id, email.stripped_text)}for (const segment of email.segments) { if (segment.kind === "quoted") view.fold(segment.text) else view.show(segment.text)}// null when there is no HTML part, or its markup could not be cutrender(email.stripped_html ?? email.html)Questions
How do I extract only the latest reply from an email thread?
Read stripped_text on the email. It is the part the sender wrote in this message: the conversation their client quoted underneath is removed, and so is a signature the thread already has. If you want the quote too, segments returns the whole body cut into written, quoted and signature parts, in order.
Why does my regex miss replies from Outlook?
Outlook puts no > in front of quoted lines. It writes a From, Sent, To and Subject block and pastes the earlier message under it, so a parser cutting at that block also cuts any answer typed below it. AI Inbx compares those lines with the message being answered, when that message is on the thread, and keeps the ones that are new.
What happens to answers typed between the quoted lines?
They stay in stripped_text, in the order they were typed, each introduced by the quoted question or sentence above it, so it still reads as an answer. The rest of the quote is removed. In segments they are written parts sitting between quoted ones.
How do I remove the signature from an email?
stripped_text leaves it out once the thread already has it from that sender. Sign-offs, the RFC signature separator and lines like Sent from my iPhone mark where a signature starts. The first signature a sender uses on a thread is kept, because that is where their name, role and phone number are; segments marks it as signature either way.
Does it work for replies written in other languages?
Yes. Attribution lines such as Am … schrieb, Le … a écrit and El … escribió are recognised along with the English one, and so are translated Outlook headers like Von and Gesendet. Answers typed into an unmarked quote are found by comparing words with the message being answered, so they are found in any language that puts spaces between words.
Can I post an email body and get the reply back?
No. There is no standalone parse call: the cut is made on mail that reaches AI Inbx, received on your domain or in a connected Gmail or Outlook mailbox, and on mail you send through it. Every email read in full, from GET /emails/{id} or a full webhook payload, then carries text, html, stripped_text, stripped_html and segments.
What if the message being answered was never on file?
Then the quote is kept in stripped_text, because nothing you hold has it: a forward, or a reply to mail sent before the mailbox was connected. segments still marks it as quoted, so you can fold it yourself.
Keep reading
More on building with email
- Inbound email APIReceive email in your app over an API. Point an MX record at AI Inbx or connect Gmail and Outlook, and every message arrives as a signed, parsed JSON webhook.ThreadingAttachmentsMailboxesWildcard domains
- Auto-reply detectionTell an out-of-office, a ticket acknowledgement or a bounce from a real reply. Every inbound email arrives with a category, decided from headers and content.MailboxesSuppressions
- Send email APISend email from your domain or your users' own Gmail and Outlook with one API call. Opt-outs and pacing are checked first, and replies land on the thread.ThreadingMailboxesPacingSuppressions