resend

📁 jsv-capital/resend-skill 📅 4 days ago
1
总安装量
1
周安装量
#54913
全站排名
安装命令
npx skills add https://github.com/jsv-capital/resend-skill --skill resend

Agent 安装分布

kilo 1
replit 1
windsurf 1
opencode 1
droid 1

Skill 文档

Resend

Email API integration for TypeScript/Node.js applications. Covers transactional email, React Email templates, domains, contacts, broadcasts, and webhooks.

Quick Start

npm install resend
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);

const { data, error } = await resend.emails.send({
  from: "App <hello@yourdomain.com>",
  to: "user@example.com",
  subject: "Hello",
  html: "<p>Hello world</p>",
});

Environment variable: RESEND_API_KEY (get from https://resend.com/api-keys).

Task Decision Tree

  1. Sending a single email → Use resend.emails.send(). See Send Email.
  2. Sending bulk emails (same API call) → Use resend.batch.send(). Max 100 per call. No attachments or scheduling.
  3. Building email templates → Use React Email components. See references/react_email.md.
  4. Setting up a domain → Use resend.domains.create(). Then add DNS records. See Domain Setup.
  5. Tracking email events → Configure webhooks in dashboard. Verify with svix. See Webhooks.
  6. Managing contacts/audiences → Use contacts API with audience IDs. See references/api_reference.md > Contacts.
  7. Sending marketing campaigns → Use broadcasts API. See references/api_reference.md > Broadcasts.
  8. Full API details for any endpoint → See references/api_reference.md.

Send Email

Single Email

const { data, error } = await resend.emails.send({
  from: "App <hello@yourdomain.com>",
  to: ["user@example.com"],
  subject: "Order Confirmed",
  html: "<h1>Your order is confirmed</h1>",
  // Optional:
  cc: ["cc@example.com"],
  bcc: ["bcc@example.com"],
  replyTo: "support@yourdomain.com",
  scheduledAt: "in 1 hour",           // or ISO 8601
  headers: { "X-Entity-Ref-ID": "123" },
  tags: [{ name: "category", value: "order" }],
  attachments: [{
    filename: "receipt.pdf",
    content: buffer,                   // Buffer or base64 string
  }],
});

With React Email

import { OrderConfirmation } from "@/emails/order-confirmation";

const { data, error } = await resend.emails.send({
  from: "App <hello@yourdomain.com>",
  to: "user@example.com",
  subject: "Order Confirmed",
  react: OrderConfirmation({ orderId: "12345", items }),
});

For React Email component patterns and the full template reference, see references/react_email.md.

Batch Send

const { data, error } = await resend.batch.send([
  { from: "App <hello@yourdomain.com>", to: "a@example.com", subject: "Hi A", html: "<p>Hello A</p>" },
  { from: "App <hello@yourdomain.com>", to: "b@example.com", subject: "Hi B", html: "<p>Hello B</p>" },
]);

Limits: max 100 emails per request, 50 recipients per email. No attachments or scheduledAt in batch.

Idempotency

Prevent duplicate sends with the Idempotency-Key header (expires 24h):

const { data, error } = await resend.emails.send(
  { from: "...", to: "...", subject: "...", html: "..." },
  { headers: { "Idempotency-Key": "order-12345-confirmation" } }
);

Check Email Status

const { data } = await resend.emails.get("email-id");
// data.last_event: "sent" | "delivered" | "bounced" | "opened" | "clicked" | "complained"

Domain Setup

1. Create Domain

const { data } = await resend.domains.create({
  name: "yourdomain.com",
  region: "us-east-1", // us-east-1 | eu-west-1 | sa-east-1 | ap-northeast-1
});

2. Add DNS Records

The response includes data.records — an array of DNS records to add:

Type Purpose
MX Mail routing
TXT (SPF) Authorize Resend to send
CNAME (DKIM) Cryptographic signing (3 records)

Add all records to your DNS provider. TTL: use Auto or the value from the response.

3. Verify

await resend.domains.verify("domain-id");

Verification can take minutes to hours depending on DNS propagation.

Domain Options

  • openTracking: true — track email opens (adds tracking pixel)
  • clickTracking: true — track link clicks (rewrites links)
  • tlsMode: "enforced" — require TLS (blocks delivery to servers without TLS)
  • capabilities: { sending: "enabled", receiving: "enabled" } — enable inbound email

Webhooks

Event Types

Event Description
email.sent Email sent to recipient server
email.delivered Accepted by recipient server
email.delivery_delayed Temporary delivery failure
email.bounced Permanent delivery failure
email.complained Marked as spam
email.opened Opened (requires open tracking)
email.clicked Link clicked (requires click tracking)

Webhook Handler (Next.js)

// app/api/webhooks/resend/route.ts
import { Webhook } from "svix";

const webhookSecret = process.env.RESEND_WEBHOOK_SECRET;

export async function POST(request: Request) {
  const body = await request.text();
  const headers = Object.fromEntries(request.headers);

  const wh = new Webhook(webhookSecret);
  let payload: any;

  try {
    payload = wh.verify(body, {
      "svix-id": headers["svix-id"],
      "svix-timestamp": headers["svix-timestamp"],
      "svix-signature": headers["svix-signature"],
    });
  } catch {
    return new Response("Invalid signature", { status: 400 });
  }

  switch (payload.type) {
    case "email.delivered":
      // Handle delivery confirmation
      break;
    case "email.bounced":
      // Handle bounce — remove/flag email address
      break;
    case "email.complained":
      // Handle spam complaint — unsubscribe user
      break;
  }

  return new Response("OK", { status: 200 });
}

Install svix: npm install svix

Next.js Integration Pattern

app/
├── api/
│   ├── send/route.ts          # Email send endpoint
│   └── webhooks/resend/route.ts  # Webhook handler
├── emails/                     # React Email templates
│   ├── welcome.tsx
│   ├── password-reset.tsx
│   └── order-confirmation.tsx
└── lib/
    └── resend.ts              # Shared Resend client

Shared client (lib/resend.ts):

import { Resend } from "resend";

if (!process.env.RESEND_API_KEY) {
  throw new Error("RESEND_API_KEY is required");
}

export const resend = new Resend(process.env.RESEND_API_KEY);

Key Constraints

  • to field: max 50 addresses per email
  • Batch send: max 100 emails per request
  • Tags: max 256 chars per name/value
  • Idempotency keys: expire after 24 hours
  • react param: Node.js SDK only (not available via REST/cURL)
  • Batch does not support attachments or scheduledAt
  • Domain must be verified before sending (use onboarding@resend.dev for testing)
  • Broadcasts can only be updated/deleted while in draft status

References