Search

PythonReactSEOPDF
GitHub 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.

mgd34msu☆ 3 Repository stars0 Repository forks

Installation

Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.

View source ↗Guides

Skill instructions

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:

  1. Single Sender Verification - Verify individual email addresses
  2. Domain Authentication - Verify entire domain (recommended for production)

Configure in SendGrid Dashboard > Settings > Sender Authentication.

Best Practices

  1. Verify your domain - Improves deliverability
  2. Use templates - Easier to maintain and update
  3. Handle bounces - Remove invalid addresses
  4. Monitor events - Track delivery and engagement
  5. Rate limit - Don't exceed plan limits
  6. Use categories - For analytics segmentation
  7. Include unsubscribe - Required for marketing emails

Examples

Read the usage examples in the source repository.

View source ↗

Source history

Indexed on
2026-01-20
Index updated
2026-01-28
Branch
main

Index and sync dates describe this directory. View the source repository for code history.

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!