Sends transactional and marketing emails with SendGrid API. Use when integrating email delivery in Node.js applications with templates, analytics, and high deliverability.
Sends transactional and marketing emails using the SendGrid API. Use this when building Node.js applications that need to deliver emails with templates, attachments, and analytics tracking.
/plugin marketplace add mgd34msu/goodvibes-plugin/plugin install goodvibes@goodvibes-marketThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Email delivery platform with high deliverability, templates, and analytics. Part of Twilio.
npm install @sendgrid/mail
import sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: 'recipient@example.com',
from: 'sender@example.com', // Must be verified sender
subject: 'Hello from SendGrid',
text: 'Plain text content',
html: '<strong>HTML content</strong>',
};
await sgMail.send(msg);
const msg = {
// Recipients
to: 'single@example.com',
// Or multiple
to: ['one@example.com', 'two@example.com'],
// Or with names
to: [
{ email: 'one@example.com', name: 'User One' },
{ email: 'two@example.com', name: 'User Two' },
],
// Sender
from: {
email: 'sender@example.com',
name: 'My App',
},
// Reply-to (optional)
replyTo: 'support@example.com',
// Subject
subject: 'Your order has shipped',
// Content
text: 'Plain text version',
html: '<h1>HTML version</h1>',
// CC and BCC
cc: 'cc@example.com',
bcc: 'bcc@example.com',
// Categories for analytics
categories: ['transactional', 'order-confirmation'],
// Custom headers
headers: {
'X-Custom-Header': 'value',
},
// Send at specific time
sendAt: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
// Attachments
attachments: [
{
content: base64EncodedContent,
filename: 'invoice.pdf',
type: 'application/pdf',
disposition: 'attachment',
},
],
};
await sgMail.send(msg);
Create templates in SendGrid dashboard with handlebars syntax.
const msg = {
to: 'recipient@example.com',
from: 'sender@example.com',
templateId: 'd-xxxxxxxxxxxxxxxxxxxxxxxx',
dynamicTemplateData: {
name: 'John',
orderNumber: '12345',
items: [
{ name: 'Product 1', price: 29.99 },
{ name: 'Product 2', price: 49.99 },
],
total: 79.98,
},
};
await sgMail.send(msg);
In your SendGrid template:
<h1>Hello {{name}}!</h1>
<p>Your order #{{orderNumber}} has shipped.</p>
<table>
{{#each items}}
<tr>
<td>{{this.name}}</td>
<td>${{this.price}}</td>
</tr>
{{/each}}
<tr>
<td><strong>Total</strong></td>
<td><strong>${{total}}</strong></td>
</tr>
</table>
const msg = {
to: ['user1@example.com', 'user2@example.com'],
from: 'sender@example.com',
subject: 'Newsletter',
html: '<p>Content for all</p>',
};
await sgMail.send(msg);
const msgs = [
{
to: 'user1@example.com',
from: 'sender@example.com',
subject: 'Hello User 1',
html: '<p>Content for User 1</p>',
},
{
to: 'user2@example.com',
from: 'sender@example.com',
subject: 'Hello User 2',
html: '<p>Content for User 2</p>',
},
];
await sgMail.send(msgs); // Sends in batch
const msg = {
from: 'sender@example.com',
subject: 'Order Update',
templateId: 'd-xxxxxx',
personalizations: [
{
to: 'user1@example.com',
dynamicTemplateData: {
name: 'Alice',
orderNumber: '001',
},
},
{
to: 'user2@example.com',
dynamicTemplateData: {
name: 'Bob',
orderNumber: '002',
},
},
],
};
await sgMail.send(msg);
import fs from 'fs';
const msg = {
to: 'recipient@example.com',
from: 'sender@example.com',
subject: 'Your invoice',
html: '<p>Please find your invoice attached.</p>',
attachments: [
{
content: fs.readFileSync('./invoice.pdf').toString('base64'),
filename: 'invoice.pdf',
type: 'application/pdf',
disposition: 'attachment',
},
{
content: fs.readFileSync('./logo.png').toString('base64'),
filename: 'logo.png',
type: 'image/png',
disposition: 'inline',
contentId: 'logo', // Reference in HTML as <img src="cid:logo">
},
],
};
await sgMail.send(msg);
try {
await sgMail.send(msg);
console.log('Email sent successfully');
} catch (error) {
console.error('Error sending email:', error);
if (error.response) {
console.error('Status code:', error.code);
console.error('Body:', error.response.body);
console.error('Headers:', error.response.headers);
}
}
| Code | Description |
|---|---|
| 400 | Bad request (check payload) |
| 401 | Unauthorized (check API key) |
| 403 | Forbidden (sender not verified) |
| 429 | Rate limit exceeded |
| 500 | SendGrid server error |
Configure in SendGrid dashboard to receive events.
// API route to receive webhooks
export async function POST(request) {
const events = await request.json();
for (const event of events) {
switch (event.event) {
case 'delivered':
console.log('Email delivered to:', event.email);
break;
case 'open':
console.log('Email opened by:', event.email);
break;
case 'click':
console.log('Link clicked:', event.url);
break;
case 'bounce':
console.log('Bounced:', event.email, event.reason);
// Remove from mailing list
break;
case 'spam_report':
console.log('Spam report from:', event.email);
// Unsubscribe user
break;
}
}
return new Response('OK');
}
For advanced operations beyond sending.
npm install @sendgrid/client
import Client from '@sendgrid/client';
const client = new Client();
client.setApiKey(process.env.SENDGRID_API_KEY);
// Get email statistics
const [response, body] = await client.request({
method: 'GET',
url: '/v3/stats',
qs: {
start_date: '2024-01-01',
end_date: '2024-01-31',
},
});
console.log(body);
// app/api/send-email/route.ts
import { NextResponse } from 'next/server';
import sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
export async function POST(request: Request) {
const { to, subject, html } = await request.json();
try {
await sgMail.send({
to,
from: process.env.SENDGRID_FROM_EMAIL!,
subject,
html,
});
return NextResponse.json({ success: true });
} catch (error) {
console.error('SendGrid error:', error);
return NextResponse.json(
{ error: 'Failed to send email' },
{ status: 500 }
);
}
}
import sgMail from '@sendgrid/mail';
import { render } from '@react-email/components';
import WelcomeEmail from './emails/welcome';
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
async function sendWelcomeEmail(user) {
const html = await render(WelcomeEmail({
name: user.name,
actionUrl: `https://myapp.com/onboarding`,
}));
await sgMail.send({
to: user.email,
from: 'welcome@myapp.com',
subject: `Welcome to MyApp, ${user.name}!`,
html,
});
}
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxx
SENDGRID_FROM_EMAIL=noreply@yourdomain.com
Before sending, verify your sender identity:
Configure in SendGrid Dashboard > Settings > Sender Authentication.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.