Wraps Logo
Inbound Email

Every inbox.
Your infrastructure.

Receive, parse, and process emails in your AWS account. Build support inboxes, automate order processing, or create email-to-ticket workflows.

SES + S3 + Lambda + EventBridge
Parse headers & attachments
Spam & virus detection
Reply with threading
inbox@yourapp.com
0 emails
customer@example.com

Order #12345 Question

Hi, I have a question about my recent order...

2m ago
support@partner.io

Integration Request

We'd like to discuss API integration options...

5m ago
noreply@service.com

Receipt for Payment #9876

Thank you for your payment. Attached is your receipt...

12m ago
lead@prospect.co

Interested in your product

I saw your demo and would love to learn more...

18m ago

The Email Pipeline

Follow the journey. From inbox to your application.

  1. Sender: Email arrives at your domain
  2. SES: AWS receives and validates
  3. S3: Raw email stored securely
  4. Lambda: Parse headers & attachments
  5. EventBridge: Trigger webhooks & rules
  6. Your App: Process and respond

Click a step to see details

Parsed Email Structure

Every field parsed. Hover to explore the structure.

Parsed Email Fields

  • emailId: Unique identifier for the inbound email
  • from: Sender address and name
  • to: Recipient addresses
  • subject: Email subject line
  • html: HTML body content
  • text: Plain text body content
  • attachments: File attachments with filename, content type, and size
  • spamVerdict: AWS SES spam detection result
  • virusVerdict: AWS SES virus scan result

Email Preview

John Doe

customer@example.com

inb_a1b2c3d4
To: support@yourapp.com

Order #12345 Question

Hi, I have a question about my order. Could you please help me track the shipment? I ordered it last week and haven't received any updates.

receipt.pdf

45.6 KB

Not Spam
No Virus

Parsed Data

InboundEmail.json
{
"emailId": "inb_a1b2c3d4",
"from": { "address": "customer@example.com", "name": "John Doe" },
"to": [{ "address": "support@yourapp.com" }],
"subject": "Order #12345 Question",
"html": "<p>Hi, I have a question about my order...</p>",
"attachments": [{ "filename": "receipt.pdf", "contentType": "application/pdf", "size": 45678 }],
"spamVerdict": "PASS",
"virusVerdict": "PASS"
}

Tap elements to see the connection

What Can You Build?

Endless possibilities. Build any email-driven workflow.

Support Inbox

Auto-create tickets from customer emails. Route by subject, extract order IDs, and assign to teams.

// EventBridge handler
const ticket = await linear.createIssue({
  title: email.subject,
  description: email.text,
  teamId: routeToTeam(email.from),
});

Order Processing

Parse order confirmations, extract tracking numbers, and update your database automatically.

// Parse order email
const tracking = extractTracking(email.html);
await db.orders.update({
  where: { email: email.from },
  data: { trackingNumber: tracking },
});

Email-to-Ticket

Integrate with Jira, Linear, GitHub Issues, or any ticketing system via webhooks.

// Create GitHub issue
await octokit.issues.create({
  owner: 'your-org',
  repo: 'support',
  title: email.subject,
  body: email.html,
});

Auto-Responders

Send acknowledgments, out-of-office replies, or follow-up sequences automatically.

// Auto-acknowledge
await email.inbox.reply(emailId, {
  from: 'support@yourapp.com',
  html: `Thanks for reaching out!
We'll respond within 24h.`,
});

Lead Capture

Extract contact information from inquiries and sync to your CRM or marketing automation.

// Sync to CRM
await hubspot.contacts.create({
  email: email.from.address,
  firstname: email.from.name,
  source: 'inbound_email',
});

Document Processing

Extract attachments, process PDFs, and trigger document workflows with S3 events.

// Process attachments
for (const att of email.attachments) {
  const file = await email.inbox
    .getAttachment(emailId, att.id);
  await processDocument(file);
}

Support Inbox

Auto-create tickets from customer emails. Route by subject, extract order IDs, and assign to teams.

// EventBridge handler
const ticket = await linear.createIssue({
  title: email.subject,
  description: email.text,
  teamId: routeToTeam(email.from),
});

Order Processing

Parse order confirmations, extract tracking numbers, and update your database automatically.

// Parse order email
const tracking = extractTracking(email.html);
await db.orders.update({
  where: { email: email.from },
  data: { trackingNumber: tracking },
});

Email-to-Ticket

Integrate with Jira, Linear, GitHub Issues, or any ticketing system via webhooks.

// Create GitHub issue
await octokit.issues.create({
  owner: 'your-org',
  repo: 'support',
  title: email.subject,
  body: email.html,
});

Auto-Responders

Send acknowledgments, out-of-office replies, or follow-up sequences automatically.

// Auto-acknowledge
await email.inbox.reply(emailId, {
  from: 'support@yourapp.com',
  html: `Thanks for reaching out!
We'll respond within 24h.`,
});

Lead Capture

Extract contact information from inquiries and sync to your CRM or marketing automation.

// Sync to CRM
await hubspot.contacts.create({
  email: email.from.address,
  firstname: email.from.name,
  source: 'inbound_email',
});

Document Processing

Extract attachments, process PDFs, and trigger document workflows with S3 events.

// Process attachments
for (const att of email.attachments) {
  const file = await email.inbox
    .getAttachment(emailId, att.id);
  await processDocument(file);
}

TypeScript SDK

Simple SDK. Full control over your inbox.

SDK Code Examples

List

import { WrapsEmail } from '@wraps.dev/email';

const email = new WrapsEmail({
  inboundBucket: 'your-bucket-name',
});

// List recent inbound emails
const { emails, cursor } = await email.inbox.list({
  limit: 20,
  from: 'customer@example.com', // optional filter
});

for (const msg of emails) {
  console.log(`${msg.from.address}: ${msg.subject}`);
}

Get

// Get full email details
const inbound = await email.inbox.get('inb_a1b2c3d4');

console.log('From:', inbound.from.name, inbound.from.address);
console.log('Subject:', inbound.subject);
console.log('HTML:', inbound.html);
console.log('Text:', inbound.text);

// Access attachments
for (const att of inbound.attachments) {
  console.log(`Attachment: ${att.filename} (${att.size} bytes)`);
}

// Check spam/virus verdicts
if (inbound.spamVerdict === 'PASS') {
  // Safe to process
}

Reply

// Reply with proper threading headers
await email.inbox.reply('inb_a1b2c3d4', {
  from: 'support@yourapp.com',
  html: `
    <p>Thanks for reaching out!</p>
    <p>We've received your message and will respond within 24 hours.</p>
    <p>Best,<br/>The Support Team</p>
  `,
});

// Threading headers (In-Reply-To, References) are
// automatically set to maintain the email chain

Forward

// Forward to your team
await email.inbox.forward('inb_a1b2c3d4', {
  to: 'team@yourcompany.com',
  from: 'forwarding@yourapp.com',
  note: 'Please review this customer inquiry.',
});

// Original message and attachments are preserved

Webhook

// EventBridge Lambda handler
export const handler = async (event: EventBridgeEvent) => {
  const email = event.detail;

  // Route based on recipient
  if (email.to[0].address.startsWith('support@')) {
    await createSupportTicket(email);
  } else if (email.to[0].address.startsWith('sales@')) {
    await notifySalesTeam(email);
  }

  // Process attachments
  if (email.attachments.length > 0) {
    await processAttachments(email);
  }

  return { statusCode: 200 };
};
TypeScriptlist-emails.ts
import { WrapsEmail } from '@wraps.dev/email';const email = new WrapsEmail({  inboundBucket: 'your-bucket-name',});// List recent inbound emailsconst { emails, cursor } = await email.inbox.list({  limit: 20,  from: 'customer@example.com', // optional filter});for (const msg of emails) {  console.log(`${msg.from.address}: ${msg.subject}`);}
InboundEmail ResponseJSON
{
  "emailId": "inb_a1b2c3d4",
  "receivedAt": "2024-01-15T10:30:00Z",
  "from": {
    "address": "customer@example.com",
    "name": "John Doe"
  },
  "to": [
    { "address": "support@yourapp.com" }
  ],
  "subject": "Order #12345 Question",
  "html": "<p>Hi, I have a question...</p>",
  "text": "Hi, I have a question...",
  "attachments": [
    {
      "id": "att_xyz789",
      "filename": "receipt.pdf",
      "contentType": "application/pdf",
      "size": 45678
    }
  ],
  "spamVerdict": "PASS",
  "virusVerdict": "PASS",
  "headers": {
    "message-id": "<abc@mail.example.com>",
    "date": "Mon, 15 Jan 2024 10:30:00 +0000"
  }
}

Your Infrastructure

Your AWS account. Your infrastructure.

Your AWS Account
Full Ownership
SES ReceiptMX Records
S3 BucketRaw Storage
LambdaParser
EventBridgeWebhooks

SES Receives

MX records route to SES

S3 Stores

Raw email saved securely

Lambda Parses

Headers, body, attachments

EventBridge Triggers

Your webhooks & rules

No Vendor Lock-in

Infrastructure stays in your AWS if you churn

Data Residency

Emails never leave your AWS account

AWS Pricing

Pay AWS directly, no markup

Ready to receive?

Start receiving emails in minutes

One command deploys inbound email infrastructure to your AWS account. Configure MX records and start processing emails.

CLI
npx @wraps.dev/cli email inbound init
No credit card requiredAWS pricing onlyFull ownership