Agent skill
sendgrid
Sends transactional and marketing emails with SendGrid API. Use when integrating email delivery in Node.js applications with templates, analytics, and high deliverability.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/sendgrid
SKILL.md
SendGrid Email API
Email delivery platform with high deliverability, templates, and analytics. Part of Twilio.
Quick Start
npm install @sendgrid/mail
Setup
import sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
Send Basic Email
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);
Email Options
Full Message Object
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);
Dynamic Templates
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);
Template Variables
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>
Multiple Recipients
Same Email to Multiple
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);
Personalized Emails (sendMultiple)
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
Personalizations (Most Efficient)
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);
Attachments
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);
Error Handling
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);
}
}
Common Errors
| 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 |
Webhooks (Event Tracking)
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');
}
Full API Client
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);
Next.js API Route
// 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 }
);
}
}
With React Email
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,
});
}
Environment Variables
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxx
SENDGRID_FROM_EMAIL=noreply@yourdomain.com
Sender Verification
Before sending, verify your sender identity:
- Single Sender Verification - Verify individual email addresses
- Domain Authentication - Verify entire domain (recommended for production)
Configure in SendGrid Dashboard > Settings > Sender Authentication.
Best Practices
- Verify your domain - Improves deliverability
- Use templates - Easier to maintain and update
- Handle bounces - Remove invalid addresses
- Monitor events - Track delivery and engagement
- Rate limit - Don't exceed plan limits
- Use categories - For analytics segmentation
- Include unsubscribe - Required for marketing emails
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?