resend
Modern email API for developers
$ npx docs2skills add resend-email-apiResend
Modern email API for developers
What this skill does
Resend is a developer-first email API that simplifies transactional email sending. It provides a clean, modern alternative to traditional SMTP services with built-in deliverability optimizations, webhooks for tracking, and support for multiple programming languages.
Unlike legacy email services, Resend focuses on developer experience with intuitive APIs, comprehensive SDKs, and features like email domain verification, activity monitoring, and event webhooks. It's designed for applications that need reliable transactional emails like user onboarding, password resets, notifications, and marketing automation.
Prerequisites
- Resend account and API key from https://resend.com/api-keys
- Verified domain (for production use)
- Node.js 16+, Python 3.7+, PHP 8.0+, or other supported runtime
- Internet connection for API calls
Quick start
Node.js
npm install resend
import { Resend } from 'resend';
const resend = new Resend('re_123456789');
const { data, error } = await resend.emails.send({
from: 'Acme <onboarding@resend.dev>',
to: ['delivered@resend.dev'],
subject: 'Hello World',
html: '<strong>It works!</strong>',
});
if (error) {
console.error(error);
} else {
console.log(data);
}
Python
pip install resend
import resend
resend.api_key = "re_123456789"
params = {
"from": "Acme <onboarding@resend.dev>",
"to": ["delivered@resend.dev"],
"subject": "Hello World",
"html": "<strong>It works!</strong>"
}
email = resend.Emails.send(params)
print(email)
Core concepts
API Key Authentication: All requests use Bearer token authentication with your API key.
Email Objects: Emails are structured with required fields (from, to, subject) and optional fields (html, text, attachments, headers).
Domain Verification: Production emails require verified domains to ensure deliverability and avoid spam filters.
Webhooks: Real-time notifications for email events (delivered, opened, clicked, bounced) sent to your endpoints.
Rate Limits: API calls are rate-limited based on your plan tier.
Key API surface
Node.js SDK
// Send email
resend.emails.send(emailObject)
// Get email by ID
resend.emails.get(emailId)
// Send batch emails
resend.batch.send([emailObject1, emailObject2])
// Domain management
resend.domains.create({ name: 'example.com' })
resend.domains.verify(domainId)
resend.domains.list()
// Contact management
resend.contacts.create({ email: 'user@example.com', audienceId })
resend.contacts.list(audienceId)
// Audience management
resend.audiences.create({ name: 'Newsletter' })
Python SDK
# Send email
resend.Emails.send(params)
# Get email
resend.Emails.get(email_id)
# Domain operations
resend.Domains.create({"name": "example.com"})
resend.Domains.verify(domain_id)
REST API
# Send email
POST https://api.resend.com/emails
# Get email
GET https://api.resend.com/emails/{email_id}
Common patterns
HTML email with attachments
await resend.emails.send({
from: 'team@company.com',
to: 'user@example.com',
subject: 'Invoice #12345',
html: `
<h1>Your Invoice</h1>
<p>Please find your invoice attached.</p>
`,
attachments: [{
filename: 'invoice.pdf',
content: fs.readFileSync('invoice.pdf'),
}]
});
Bulk email sending
const emails = users.map(user => ({
from: 'newsletter@company.com',
to: user.email,
subject: `Hi ${user.name}!`,
html: `<p>Personal message for ${user.name}</p>`
}));
const { data } = await resend.batch.send(emails);
Email templates with variables
await resend.emails.send({
from: 'noreply@company.com',
to: user.email,
subject: 'Welcome aboard!',
html: `
<h1>Welcome ${user.name}!</h1>
<p>Your account ${user.email} is ready.</p>
<a href="${process.env.APP_URL}/verify?token=${user.token}">
Verify Email
</a>
`
});
Webhook handling (Express)
app.post('/webhooks/resend', (req, res) => {
const { type, data } = req.body;
switch (type) {
case 'email.delivered':
console.log(`Email ${data.email_id} delivered`);
break;
case 'email.bounced':
console.log(`Email ${data.email_id} bounced`);
break;
}
res.status(200).send('OK');
});
Configuration
Environment variables
RESEND_API_KEY=re_your_api_key_here
Domain setup
- Add domain in Resend dashboard
- Add DNS records (SPF, DKIM, DMARC)
- Verify domain status
- Use verified domain in 'from' field
Webhook configuration
// Configure webhook endpoint in Resend dashboard
// Handle these events: delivered, bounced, complained, opened, clicked
Best practices
- Always use verified domains for production emails
- Handle both
dataanderrorresponses from API calls - Implement exponential backoff for failed requests
- Use environment variables for API keys, never hardcode
- Validate email addresses before sending
- Implement webhook endpoints for delivery tracking
- Use batch sending for multiple emails to improve performance
- Include both HTML and text versions for better compatibility
- Set appropriate reply-to addresses for transactional emails
- Monitor your sending reputation through the Resend dashboard
Gotchas and common mistakes
Unverified domains: Emails from unverified domains may be rejected or marked as spam. Always verify domains in production.
Rate limiting: Free tier has strict rate limits. Implement proper error handling for 429 responses.
Email format validation: Resend validates email formats strictly. Malformed addresses will cause API errors.
Attachment size limits: Attachments are limited to 40MB total per email.
Webhook verification: Resend doesn't provide webhook signature verification yet - implement IP allowlisting.
API key exposure: Never commit API keys to version control. Use environment variables.
Bounce handling: Implement webhook handlers for bounces to maintain sender reputation.
HTML encoding: Properly escape user data in HTML templates to prevent XSS.
Subject line limits: Subject lines over 78 characters may be truncated by email clients.
Testing vs production: Use different API keys and domains for development and production environments.
Async/await errors: Always wrap Resend calls in try-catch blocks or handle promise rejections.
Batch limits: Batch sending is limited to 100 emails per request.