Resend
Send transactional and marketing email with Resend. Use this skill when the
You are an email operations specialist who integrates Resend into projects. You
understand transactional vs marketing email, deliverability, compliance, and the
full Resend API surface including sends, contacts, audiences, broadcasts, and webhooks.
## Key Points
- `category`: `security`, `billing`, `account`, `product`, `newsletter`
- `workflow`: exact workflow name like `payment_confirmation`
- `environment`: `dev`, `staging`, `prod`
- Always include both HTML and plain-text content
- Keep transactional emails minimal — no promotional sidebars
- Use a subdomain for sending to isolate domain reputation
- Warm new domains gradually — start with engaged recipients
- Verify webhook signatures in production
- Store Resend email IDs for debugging and support
- Remove hard bounces and complaint addresses immediately
- Keep subjects honest and specific — no clickbait
- Mixing marketing content into receipts or password resets
## Quick Example
```bash
npm install resend
```
```typescript
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
```skilldb get email-services-skills/ResendFull skill: 245 linesResend Email Integration
You are an email operations specialist who integrates Resend into projects. You understand transactional vs marketing email, deliverability, compliance, and the full Resend API surface including sends, contacts, audiences, broadcasts, and webhooks.
Core Philosophy
Classify before you send
Every email falls into one of three buckets: transactional (triggered by user action, required for service), operational (useful but not marketing), or marketing (requires consent). Misclassifying causes deliverability and compliance problems.
Local-first reliability
Send calls fail. Networks drop. Use idempotency keys for every retryable send so duplicate deliveries never happen. Log every send attempt with the Resend email ID for traceability.
Separation of streams
Never mix promotional content into password resets or receipts. Keep transactional and marketing emails on separate logical streams. This protects deliverability and builds recipient trust.
Setup
Install
npm install resend
Initialize client
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
Domain verification
Verify your sending domain in the Resend dashboard. Configure SPF, DKIM, and DMARC
DNS records. Use a subdomain like mail.yourdomain.com for transactional email to
isolate reputation from your root domain.
Key Techniques
Single send
Use for transactional email — one recipient, immediate delivery, optional scheduling.
const { data, error } = await resend.emails.send({
from: 'App <noreply@mail.yourdomain.com>',
to: 'user@example.com',
subject: 'Your password reset link',
html: '<p>Click <a href="...">here</a> to reset.</p>',
text: 'Reset your password: https://...',
tags: [
{ name: 'category', value: 'security' },
{ name: 'workflow', value: 'password_reset' },
],
headers: {
'X-Entity-Ref-ID': `password-reset/${userId}/${requestId}`,
},
});
Batch send
Send up to 100 distinct emails in one API call. No attachments or per-recipient scheduling. Good for digest emails or notifications to multiple users.
const { data, error } = await resend.batch.send([
{
from: 'App <noreply@mail.yourdomain.com>',
to: 'user1@example.com',
subject: 'Your weekly summary',
html: user1SummaryHtml,
},
{
from: 'App <noreply@mail.yourdomain.com>',
to: 'user2@example.com',
subject: 'Your weekly summary',
html: user2SummaryHtml,
},
]);
Scheduled send
Schedule an email for future delivery.
await resend.emails.send({
from: 'App <noreply@mail.yourdomain.com>',
to: 'user@example.com',
subject: 'Your trial ends tomorrow',
html: trialEndingHtml,
scheduledAt: '2025-12-25T09:00:00Z',
});
React Email templates
Build type-safe, component-based email templates with React Email.
npm install @react-email/components
import { Html, Head, Body, Container, Text, Button } from '@react-email/components';
export function WelcomeEmail({ name, url }: { name: string; url: string }) {
return (
<Html>
<Head />
<Body style={{ backgroundColor: '#0a0a0f', fontFamily: 'sans-serif' }}>
<Container>
<Text>Welcome, {name}</Text>
<Button href={url}>Get Started</Button>
</Container>
</Body>
</Html>
);
}
import { render } from '@react-email/render';
import { WelcomeEmail } from './emails/welcome';
const html = await render(WelcomeEmail({ name: 'Alice', url: 'https://...' }));
await resend.emails.send({ from, to, subject: 'Welcome', html });
Contacts and audiences
Manage subscriber lists with custom properties for segmentation.
// Create audience
const audience = await resend.audiences.create({ name: 'Newsletter' });
// Add contact
await resend.contacts.create({
audienceId: audience.data.id,
email: 'user@example.com',
firstName: 'Alice',
unsubscribed: false,
});
Broadcasts
Send campaigns to audiences with personalization.
const broadcast = await resend.broadcasts.create({
audienceId: 'aud_xxx',
from: 'Updates <updates@mail.yourdomain.com>',
subject: 'What shipped this week',
html: newsletterHtml,
});
await resend.broadcasts.send(broadcast.data.id);
Webhook Processing
Register a webhook endpoint in the Resend dashboard. Process these events:
| Event | Action |
|---|---|
email.delivered | Mark as delivered in message log |
email.bounced | Flag address, suppress if hard bounce |
email.complained | Immediately suppress from non-essential sends |
email.failed | Log failure, alert if critical email |
email.opened | Update engagement metrics (marketing only) |
email.clicked | Update engagement metrics (marketing only) |
// Webhook handler (Next.js example)
export async function POST(req: Request) {
const body = await req.json();
const { type, data } = body;
switch (type) {
case 'email.bounced':
await suppressAddress(data.to[0], 'bounce');
break;
case 'email.complained':
await suppressAddress(data.to[0], 'complaint');
break;
}
return Response.json({ received: true });
}
Idempotency Keys
Use stable, deterministic keys for retryable sends:
| Email type | Key pattern |
|---|---|
| Password reset | password-reset/{userId}/{requestId} |
| Payment confirmation | payment-confirm/{invoiceId} |
| Weekly digest | weekly-digest/{userId}/{yearWeek} |
| Welcome | welcome/{email} |
Pass via the X-Entity-Ref-ID header or Resend's idempotency key parameter.
Tag Taxonomy
Attach tags to every send for analytics and webhook routing:
category:security,billing,account,product,newsletterworkflow: exact workflow name likepayment_confirmationenvironment:dev,staging,prod
Best Practices
- Always include both HTML and plain-text content
- Keep transactional emails minimal — no promotional sidebars
- Use a subdomain for sending to isolate domain reputation
- Warm new domains gradually — start with engaged recipients
- Verify webhook signatures in production
- Store Resend email IDs for debugging and support
- Remove hard bounces and complaint addresses immediately
- Keep subjects honest and specific — no clickbait
Anti-Patterns
- Mixing marketing content into receipts or password resets
- Retrying sends without idempotency keys
- Ignoring bounce and complaint webhook events
- Sending from an unverified or unauthenticated domain
- Tracking opens/clicks on security-sensitive transactional email
- Using one catch-all list with no topic preferences
- Storing API keys in client-side code
Install this skill directly: skilldb add email-services-skills
Related Skills
AWS Ses
Send email at scale with Amazon SES (Simple Email Service). Use this skill when
Brevo
Send transactional and marketing email with Brevo (formerly Sendinblue). Use this
Courier
Send transactional notifications including email with Courier. Use this skill when
Customerio
Send transactional and marketing email with Customer.io. Use this skill when the
Email Deliverability
Optimize email deliverability across any provider. Use this skill when the project
Loops
Send transactional and marketing email with Loops. Use this skill when the project