Solutions
Email Parsing API: Inbound Mail as Structured JSON, Zero MIME Handling
An email parsing API takes a raw inbound message — MIME multiparts, HTML, encoded headers and all — and delivers a clean, structured JSON event to your endpoint instead: sender, subject, plain-text body, thread identifier, attachment metadata, and a prompt-injection score, ready for your code or your LLM to consume directly. Mails.ai does this as a managed service: you register a webhook or open the SSE stream, and parsed events arrive the moment mail lands.
From raw MIME to typed JSON in one hop
The typical path to parsed inbound email: configure MX records, set up an IMAP client, handle OAuth token refresh, fetch raw messages, load a MIME parser, strip HTML, decode quoted-printable, reconstruct threads from In-Reply-To headers. Mails.ai collapses that into a single webhook call:
// What your endpoint receives — no parsing needed on your side
{
"event": "message.received",
"message_id": "msg_01jx8kpq2mfr4v",
"thread_id": "thr_01jx4nbq8cde7w",
"from": { "address": "alice@example.com", "name": "Alice" },
"to": [{ "address": "support@yourworkspace.mails.ai" }],
"subject": "Re: Order #2241",
"body_text": "Hi — still waiting on the tracking number for my order.",
"body_html": "<p>Hi — still waiting on the tracking number for my order.</p>",
"injection_score": 0.02,
"attachments": [],
"received_at": "2026-09-06T08:14:02Z"
}Thread reconstruction is automatic: every reply carries the same thread_id as the original message, so your agent or handler can retrieve the full conversation context in one query without parsing In-Reply-To headers yourself.
Register a webhook — parsing starts immediately
Give each inbox its own address (or bring a custom domain), register your endpoint, and every inbound message is parsed and POSTed to you:
import Mails from "@mailsai/sdk";
const mails = new Mails({ apiKey: process.env.MAILS_API_KEY });
// One-time: register a webhook for parsed inbound events
await mails.webhooks.create({
url: "https://your-app.com/api/email",
events: ["message.received"],
});
// Or skip the webhook entirely — use the SSE stream or long-poll
for await (const event of mails.events.stream({ type: "message.received" })) {
const { body_text, thread_id, injection_score, from } = event;
// body_text is already plain-text — no HTML stripping, no MIME decoding
if ((injection_score ?? 0) > 0.5) {
// Treat as suspicious; skip or quarantine
continue;
}
// Reply in the same thread — no Message-ID wrangling
await mails.messages.reply(event.message_id, {
body_text: `Hi ${from.name ?? from.address} — on it, will follow up shortly.`,
});
}Parsing is the product, not a feature
Unlike add-on inbound parsing from a transactional provider, the parsing layer here is first-class: multipart MIME is unwrapped, HTML is stripped to clean plain text, attachments surface as typed metadata (filename, content-type, size, inline vs. attached), and Base64-encoded bodies are decoded before delivery. When you need the raw source for auditing, it is available separately — but your handler receives the clean form by default.
Optional intent and entity classification — enabled per address or globally — adds intent, entities, and urgency fields to each parsed event at $0.003 per message. Useful when you want routing logic (high-urgency → escalate, refund-intent → billing agent) decided before your LLM runs rather than inside it.
For a deeper look at the inbound architecture — SES inbound → Lambda → structured event — see the inbound email parsing feature page.
Pricing
Parsed inbound events cost $0.002 each, including MIME handling, HTML stripping, thread reconstruction, and the injection-score scan. Intent classification is $0.003 more when enabled. The free tier covers 3,000 inbound messages per month — no card required to start. For workloads that need a dedicated address with its own MX routing, see the inbound email API for AI agents page. For outbound from the same parsed inbox, AI email agent covers the full bidirectional flow. Building the webhook handler in Python? See Email API with Webhooks for Inbound Messages — Python AI Agents for Flask and FastAPI patterns with HMAC signature verification.
Frequently asked questions
Why use an email parsing API instead of a library like mailparser or postal-mime?
A library parses a message you already fetched — which means you still need IMAP polling, OAuth refresh, and MIME retrieval to get the raw bytes in the first place. A managed email parsing API receives the message for you (via MX record), parses it server-side, and pushes a structured event to your webhook. You write a POST handler, not an email stack.
What fields does the parsed event include?
Every event includes: from (address + display name), to, subject, body_text (clean plain text, HTML stripped), body_html (when present), thread_id (stable across a full conversation), message_id, in_reply_to, attachment metadata (filename, content-type, size), and injection_score (0.0–1.0). Optional intent classification adds intent, entities, and urgency when you enable it.
Is webhook delivery the only option, or can I poll?
Three delivery modes: webhook (HTTPS POST, HMAC-signed, retried with exponential backoff), long-poll (GET /v1/events with filters), and SSE streaming (GET /v1/events/stream — holds the connection open and pushes events as they arrive). All three produce the same parsed JSON payload.
What does the injection-score field protect against?
Every inbound message is scanned for prompt-injection patterns before the parsed event is delivered. The score (0.0 = clean, 1.0 = high-confidence injection) lets your code branch on a number rather than relying on the LLM to notice it is being attacked inside the same prompt as the attack. Quarantine logic: if injection_score > 0.5, handle with elevated scrutiny.
Explore the product
Built for agents.
Self-serve in minutes.
The API is live and self-serve. Drop ~6 lines into your agent and ship.
$ npm install @mailsai/sdk