Skip to main content

Use Cases

Support Tickets

Create tickets from customer emails automatically

Email Parsing

Extract data from invoices, receipts, and forms

Automations

Trigger workflows when emails arrive

How It Works

1

Configure MX

Point your domain’s MX records to Unosend
2

Email Received

We receive and parse incoming emails
3

Spam Check

SPF, DKIM, DMARC validation
4

Webhook/API

Get notified or fetch via API

Setup Guide

1

Verify Your Domain

Go to Domains in your dashboard and add your domain. Complete the DNS verification by adding the required TXT record.
2

Enable Inbound Emails

Click the menu on your domain and select Inbound Settings. Toggle “Enable Inbound Emails” to on.
Optional: Configure a webhook URL to receive real-time notifications, or set a forward-to email address.
3

Add MX Records

Add the following MX record to your domain’s DNS settings:
Type:     MX
Host:     @ (or your subdomain)
Priority: 10
Value:    inbound.unosend.co
If you’re using a subdomain (e.g., mail.yourdomain.com), set the Host to that subdomain instead of @.
4

Done!

Emails sent to [email protected] will now be received by Unosend. View them in the Inbound section of your dashboard or via the API.

Webhook Notifications

When an email arrives, we’ll send a POST request to your configured webhook URL:
email.received webhook
{
  "type": "email.received",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "from": "[email protected]",
    "from_name": "John Doe",
    "to": ["[email protected]"],
    "cc": null,
    "subject": "Need help with my order",
    "has_html": true,
    "has_text": true,
    "attachment_count": 1,
    "spam_status": "clean",
    "received_at": "2024-01-15T10:30:00.000Z"
  },
  "timestamp": "2024-01-15T10:30:00.000Z"
}
The webhook contains metadata only. Use the email id to fetch the full content (HTML, text, attachments) via the API.

Fetching Email Content

Use the API to retrieve the full email content:
cURL
curl https://www.unosend.co/api/v1/inbound/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer un_your_api_key"

Response

Response
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "from": "[email protected]",
  "from_name": "John Doe",
  "to": ["[email protected]"],
  "subject": "Need help with my order",
  "html": "<html><body><p>Hi, I need help...</p></body></html>",
  "text": "Hi, I need help...",
  "headers": {
    "Message-ID": "<[email protected]>",
    "Date": "Mon, 15 Jan 2024 10:30:00 +0000"
  },
  "attachments": [
    {
      "id": "att_xxxxxxxxx",
      "filename": "invoice.pdf",
      "content_type": "application/pdf",
      "size": 102400
    }
  ],
  "spam_score": 0.2,
  "spam_status": "clean",
  "spf_result": "pass",
  "dkim_result": "pass",
  "dmarc_result": "pass",
  "received_at": "2024-01-15T10:30:00.000Z"
}

Downloading Attachments

Download attachments using the attachment ID:
cURL
curl https://www.unosend.co/api/v1/inbound/attachments/att_xxxxxxxxx \
  -H "Authorization: Bearer un_your_api_key" \
  --output invoice.pdf
The response includes the file with appropriate Content-Type and Content-Disposition headers.

Spam Filtering

All inbound emails are automatically checked for spam. We validate:
CheckDescription
spf_resultSender Policy Framework validation
dkim_resultDomainKeys Identified Mail signature
dmarc_resultDMARC policy alignment
spam_scoreSpamAssassin score (lower is better)
spam_statusclean, suspicious, or spam
Emails with a spam score above 5.0 are marked as spam. You can filter these in the dashboard or via the API.

Code Examples

Webhook Handler (Next.js)

app/api/webhooks/inbound/route.ts
import { NextRequest, NextResponse } from 'next/server'
import crypto from 'crypto'

const WEBHOOK_SECRET = process.env.INBOUND_WEBHOOK_SECRET!

export async function POST(request: NextRequest) {
  const body = await request.text()
  const signature = request.headers.get('x-webhook-signature')

  // Verify webhook signature
  const expectedSig = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(body)
    .digest('hex')

  if (signature !== expectedSig) {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 })
  }

  const payload = JSON.parse(body)

  if (payload.type === 'email.received') {
    const { id, from, subject, attachment_count } = payload.data

    // Create support ticket, trigger automation, etc.
    console.log(`New email from ${from}: ${subject}`)

    // Fetch full content if needed
    if (attachment_count > 0) {
      const response = await fetch(
        `https://www.unosend.co/api/v1/inbound/${id}`,
        { headers: { Authorization: `Bearer ${process.env.UNOSEND_API_KEY}` } }
      )
      const email = await response.json()
      // Process attachments...
    }
  }

  return NextResponse.json({ received: true })
}

List Inbound Emails (Node.js)

list-inbound.js
import { Unosend } from '@unosend/node'

const unosend = new Unosend('un_your_api_key')

// List recent inbound emails
const { data: emails } = await unosend.inbound.list({
  limit: 50,
  status: 'received'
})

for (const email of emails) {
  console.log(`From: ${email.from}`)
  console.log(`Subject: ${email.subject}`)
  console.log(`Attachments: ${email.attachment_count}`)
  console.log('---')
}

Webhook Handler (Express)

server.js
const express = require('express')
const crypto = require('crypto')

const app = express()
app.use(express.json())

app.post('/webhooks/inbound', (req, res) => {
  const signature = req.headers['x-webhook-signature']
  const body = JSON.stringify(req.body)

  // Verify signature
  const expectedSig = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(body)
    .digest('hex')

  if (signature !== expectedSig) {
    return res.status(401).json({ error: 'Invalid signature' })
  }

  const { type, data } = req.body

  if (type === 'email.received') {
    // Process the inbound email
    console.log('New email:', data.subject)
    
    // Create ticket, notify team, etc.
  }

  res.json({ received: true })
})

Limits

LimitValue
Max email size30 MB
Max attachment size25 MB
Email retention30 days
Webhook timeout30 seconds
Webhook retries3 attempts

FAQ

Yes! You can set up inbound on a subdomain like mail.yourdomain.com to keep your main domain’s MX records unchanged.
We retry failed webhooks 3 times with exponential backoff. Emails are always stored and can be retrieved via the API regardless of webhook status.
Yes! In the Inbound Settings, you can specify a forward-to email address. All incoming emails will be forwarded automatically.
When inbound is enabled, all emails to any address at your domain are received. The to field shows the exact recipient address.