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
Configure MX
Point your domain’s MX records to Unosend
Email Received
We receive and parse incoming emails
Spam Check
SPF, DKIM, DMARC validation
Webhook/API
Get notified or fetch via API
Setup Guide
Verify Your Domain
Go to Domains in your dashboard and add your domain. Complete the DNS verification by adding the required TXT record.
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.
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 @.
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:
{
"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 https://www.unosend.co/api/v1/inbound/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer un_your_api_key"
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 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:
Check Description 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)
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)
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
Limit Value Max email size 30 MB Max attachment size 25 MB Email retention 30 days Webhook timeout 30 seconds Webhook retries 3 attempts
FAQ
Can I use a subdomain for inbound?
Yes! You can set up inbound on a subdomain like mail.yourdomain.com to keep your main domain’s MX records unchanged.
What happens if my webhook is down?
We retry failed webhooks 3 times with exponential backoff. Emails are always stored and can be retrieved via the API regardless of webhook status.
Can I forward emails to another address?
Yes! In the Inbound Settings, you can specify a forward-to email address. All incoming emails will be forwarded automatically.
How do I handle catch-all addresses?
When inbound is enabled, all emails to any address at your domain are received. The to field shows the exact recipient address.